Merge
authorjwilhelm
Tue, 13 Dec 2016 02:04:23 +0100
changeset 42864 194398a04b7e
parent 42662 ba98de0931bb (current diff)
parent 42502 cf139f925da0 (diff)
child 42865 b9f19a575020
child 42866 97de8ed6c6b3
Merge
jdk/src/java.httpclient/share/classes/java/net/http/AsyncConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/AsyncEvent.java
jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java
jdk/src/java.httpclient/share/classes/java/net/http/AuthenticationFilter.java
jdk/src/java.httpclient/share/classes/java/net/http/BufferHandler.java
jdk/src/java.httpclient/share/classes/java/net/http/ByteBufferConsumer.java
jdk/src/java.httpclient/share/classes/java/net/http/ByteBufferGenerator.java
jdk/src/java.httpclient/share/classes/java/net/http/CharsetToolkit.java
jdk/src/java.httpclient/share/classes/java/net/http/ConnectionPool.java
jdk/src/java.httpclient/share/classes/java/net/http/ContinuationFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/CookieFilter.java
jdk/src/java.httpclient/share/classes/java/net/http/DataFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/ErrorFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java
jdk/src/java.httpclient/share/classes/java/net/http/ExchangeImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/ExecutorWrapper.java
jdk/src/java.httpclient/share/classes/java/net/http/FilterFactory.java
jdk/src/java.httpclient/share/classes/java/net/http/FrameReader.java
jdk/src/java.httpclient/share/classes/java/net/http/GoAwayFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/HeaderFilter.java
jdk/src/java.httpclient/share/classes/java/net/http/HeaderFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/HeaderParser.java
jdk/src/java.httpclient/share/classes/java/net/http/HeadersFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/Http1Exchange.java
jdk/src/java.httpclient/share/classes/java/net/http/Http1Request.java
jdk/src/java.httpclient/share/classes/java/net/http/Http1Response.java
jdk/src/java.httpclient/share/classes/java/net/http/Http2ClientImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/Http2Connection.java
jdk/src/java.httpclient/share/classes/java/net/http/Http2Frame.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpClient.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpClientBuilderImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpHeaders.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpHeadersImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpRedirectImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpRequest.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestBuilderImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpResponse.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/HttpTimeoutException.java
jdk/src/java.httpclient/share/classes/java/net/http/ImmutableHeaders.java
jdk/src/java.httpclient/share/classes/java/net/http/Log.java
jdk/src/java.httpclient/share/classes/java/net/http/MultiExchange.java
jdk/src/java.httpclient/share/classes/java/net/http/OutgoingHeaders.java
jdk/src/java.httpclient/share/classes/java/net/http/Pair.java
jdk/src/java.httpclient/share/classes/java/net/http/PingFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/PlainHttpConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/PlainProxyConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/PlainTunnelingConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/PriorityFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/PushPromiseFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/Queue.java
jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java
jdk/src/java.httpclient/share/classes/java/net/http/RawChannelImpl.java
jdk/src/java.httpclient/share/classes/java/net/http/RedirectFilter.java
jdk/src/java.httpclient/share/classes/java/net/http/ResetFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/ResponseContent.java
jdk/src/java.httpclient/share/classes/java/net/http/ResponseHeaders.java
jdk/src/java.httpclient/share/classes/java/net/http/SSLConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/SSLDelegate.java
jdk/src/java.httpclient/share/classes/java/net/http/SSLTunnelConnection.java
jdk/src/java.httpclient/share/classes/java/net/http/SettingsFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/Stream.java
jdk/src/java.httpclient/share/classes/java/net/http/TimeoutEvent.java
jdk/src/java.httpclient/share/classes/java/net/http/Utils.java
jdk/src/java.httpclient/share/classes/java/net/http/WS.java
jdk/src/java.httpclient/share/classes/java/net/http/WSBuilder.java
jdk/src/java.httpclient/share/classes/java/net/http/WSCharsetToolkit.java
jdk/src/java.httpclient/share/classes/java/net/http/WSDisposable.java
jdk/src/java.httpclient/share/classes/java/net/http/WSFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java
jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java
jdk/src/java.httpclient/share/classes/java/net/http/WSMessageSender.java
jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java
jdk/src/java.httpclient/share/classes/java/net/http/WSOutgoingMessage.java
jdk/src/java.httpclient/share/classes/java/net/http/WSProtocolException.java
jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java
jdk/src/java.httpclient/share/classes/java/net/http/WSShared.java
jdk/src/java.httpclient/share/classes/java/net/http/WSSharedPool.java
jdk/src/java.httpclient/share/classes/java/net/http/WSSignalHandler.java
jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java
jdk/src/java.httpclient/share/classes/java/net/http/WSUtils.java
jdk/src/java.httpclient/share/classes/java/net/http/WSWriter.java
jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java
jdk/src/java.httpclient/share/classes/java/net/http/WebSocketHandshakeException.java
jdk/src/java.httpclient/share/classes/java/net/http/WindowUpdateFrame.java
jdk/src/java.httpclient/share/classes/java/net/http/package-info.java
jdk/src/java.httpclient/share/classes/module-info.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BinaryRepresentationWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BulkSizeUpdateWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Decoder.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/DecodingCallback.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Encoder.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/HeaderTable.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Huffman.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/ISO_8859_1.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexNameValueWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexedWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerReader.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralNeverIndexedWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWithIndexingWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/SizeUpdateWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringReader.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringWriter.java
jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/package-info.java
jdk/test/java/net/InetAddress/ptr/lookup.sh
jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.sh
jdk/test/java/net/httpclient/BasicWebSocketAPITest.java
jdk/test/java/net/httpclient/HttpUtils.java
jdk/test/java/net/httpclient/QuickResponses.java
jdk/test/java/net/httpclient/TimeoutTest.java
jdk/test/java/net/httpclient/http2/TEST.properties
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/BodyInputStream.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/BodyOutputStream.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/EchoHandler.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2Handler.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestExchange.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServerConnection.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/OutgoingPushPromise.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/PushHandler.java
jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/TestUtil.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BinaryPrimitivesTest.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BuffersTestingKit.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/CircularBufferTest.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/DecoderTest.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/EncoderTest.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HeaderTableTest.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HuffmanTest.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/SpecHelper.java
jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/TestHelper.java
jdk/test/java/net/httpclient/whitebox/java.httpclient/java/net/http/SelectorTest.java
--- a/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -390,3 +390,4 @@
 3ee4e7827413fa5c5c4fca58597b0ad89e921bfb jdk-9+145
 581331db696a62dd411926ba7fd437252252a71d jdk-9+146
 f4e854a77aa38749bd90f722b06974a56e7233d5 jdk-9+147
+5c71ea43933b6c7e8a85eb1a4eb2213011b95d82 jdk-9+148
--- a/.hgtags-top-repo	Fri Dec 16 01:46:00 2016 -0800
+++ b/.hgtags-top-repo	Tue Dec 13 02:04:23 2016 +0100
@@ -390,3 +390,4 @@
 ff98aa9ec9fae991e426ce5926fc9036d25f5562 jdk-9+145
 a22e2671d88f6b22a4aa82e3966986542ed2a381 jdk-9+146
 5f6920274c48eb00d31afee6c034826a754c13d9 jdk-9+147
+3ffc3e886c74736e387f3685e86b557cdea706c8 jdk-9+148
--- a/common/autoconf/generated-configure.sh	Fri Dec 16 01:46:00 2016 -0800
+++ b/common/autoconf/generated-configure.sh	Tue Dec 13 02:04:23 2016 +0100
@@ -671,6 +671,8 @@
 LLVM_LDFLAGS
 LLVM_CFLAGS
 LLVM_CONFIG
+LIBFFI_LIB_FILE
+ENABLE_LIBFFI_BUNDLING
 LIBFFI_LIBS
 LIBFFI_CFLAGS
 ALSA_LIBS
@@ -1208,6 +1210,7 @@
 with_libffi
 with_libffi_include
 with_libffi_lib
+enable_libffi_bundling
 with_libjpeg
 with_giflib
 with_libpng
@@ -1990,6 +1993,9 @@
                           disable bundling of the freetype library with the
                           build result [enabled on Windows or when using
                           --with-freetype, disabled otherwise]
+  --enable-libffi-bundling
+                          enable bundling of libffi.so to make the built JDK
+                          runnable on more systems
   --enable-jtreg-failure-handler
                           forces build of the jtreg failure handler to be
                           enabled, missing dependencies become fatal errors.
@@ -4171,7 +4177,7 @@
     ffi)
       PKGHANDLER_COMMAND="sudo apt-get install libffi-dev" ;;
     x11)
-      PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
+      PKGHANDLER_COMMAND="sudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
     ccache)
       PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
     dtrace)
@@ -5082,7 +5088,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1480714260
+DATE_WHEN_GENERATED=1481104795
 
 ###############################################################################
 #
@@ -24451,11 +24457,10 @@
     fi
   else
     if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
-      # Default is to calculate a string like this <timestamp>.<username>.<base dir name>
-      timestamp=`$DATE '+%Y-%m-%d-%H%M%S'`
+      # Default is to calculate a string like this 'adhoc.<username>.<base dir name>'
       # Outer [ ] to quote m4.
        basedirname=`$BASENAME "$TOPDIR" | $TR -d -c '[a-z][A-Z][0-9].-'`
-      VERSION_OPT="$timestamp.$USERNAME.$basedirname"
+      VERSION_OPT="adhoc.$USERNAME.$basedirname"
     fi
   fi
 
@@ -62634,6 +62639,11 @@
   withval=$with_libffi_lib;
 fi
 
+  # Check whether --enable-libffi-bundling was given.
+if test "${enable_libffi_bundling+set}" = set; then :
+  enableval=$enable_libffi_bundling;
+fi
+
 
   if test "x$NEEDS_LIB_FFI" = xfalse; then
     if (test "x${with_libffi}" != x && test "x${with_libffi}" != xno) || \
@@ -62652,6 +62662,7 @@
     fi
 
     if test "x${with_libffi}" != x; then
+      LIBFFI_LIB_PATH="${with_libffi}/lib"
       LIBFFI_LIBS="-L${with_libffi}/lib -lffi"
       LIBFFI_CFLAGS="-I${with_libffi}/include"
       LIBFFI_FOUND=yes
@@ -62661,6 +62672,7 @@
       LIBFFI_FOUND=yes
     fi
     if test "x${with_libffi_lib}" != x; then
+      LIBFFI_LIB_PATH="${with_libffi_lib}"
       LIBFFI_LIBS="-L${with_libffi_lib} -lffi"
       LIBFFI_FOUND=yes
     fi
@@ -62870,7 +62882,70 @@
 
       as_fn_error $? "Found libffi but could not link and compile with it. $HELP_MSG" "$LINENO" 5
     fi
-  fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libffi should be bundled" >&5
+$as_echo_n "checking if libffi should be bundled... " >&6; }
+    if test "x$enable_libffi_bundling" = "x"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+      ENABLE_LIBFFI_BUNDLING=false
+    elif  test "x$enable_libffi_bundling" = "xno"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5
+$as_echo "no, forced" >&6; }
+      ENABLE_LIBFFI_BUNDLING=false
+    elif  test "x$enable_libffi_bundling" = "xyes"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, forced" >&5
+$as_echo "yes, forced" >&6; }
+      ENABLE_LIBFFI_BUNDLING=true
+    else
+      as_fn_error $? "Invalid value for --enable-libffi-bundling" "$LINENO" 5
+    fi
+
+    # Find the libffi.so.X to bundle
+    if test "x${ENABLE_LIBFFI_BUNDLING}" = "xtrue"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libffi lib file location" >&5
+$as_echo_n "checking for libffi lib file location... " >&6; }
+      if test "x${LIBFFI_LIB_PATH}" != x; then
+        if test -e ${LIBFFI_LIB_PATH}/libffi.so.?; then
+          LIBFFI_LIB_FILE="${LIBFFI_LIB_PATH}/libffi.so.?"
+        else
+          as_fn_error $? "Could not locate libffi.so.? for bundling in ${LIBFFI_LIB_PATH}" "$LINENO" 5
+        fi
+      else
+        # If we don't have an explicit path, look in a few obvious places
+        if test "x${OPENJDK_TARGET_CPU}" = "xx86"; then
+          if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
+          elif test -e ${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.?"
+          else
+            as_fn_error $? "Could not locate libffi.so.? for bundling" "$LINENO" 5
+          fi
+        elif test "x${OPENJDK_TARGET_CPU}" = "xx86_64"; then
+          if test -e ${SYSROOT}/usr/lib64/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib64/libffi.so.?"
+          elif test -e ${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.?"
+          else
+            as_fn_error $? "Could not locate libffi.so.? for bundling" "$LINENO" 5
+          fi
+        else
+          # Fallback on the default /usr/lib dir
+          if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
+          else
+            as_fn_error $? "Could not locate libffi.so.? for bundling" "$LINENO" 5
+          fi
+        fi
+      fi
+      # Make sure the wildcard is evaluated
+      LIBFFI_LIB_FILE="$(ls ${LIBFFI_LIB_FILE})"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBFFI_LIB_FILE}" >&5
+$as_echo "${LIBFFI_LIB_FILE}" >&6; }
+    fi
+  fi
+
+
 
 
 
--- a/common/autoconf/help.m4	Fri Dec 16 01:46:00 2016 -0800
+++ b/common/autoconf/help.m4	Tue Dec 13 02:04:23 2016 +0100
@@ -116,7 +116,7 @@
     ffi)
       PKGHANDLER_COMMAND="sudo apt-get install libffi-dev" ;;
     x11)
-      PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
+      PKGHANDLER_COMMAND="sudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
     ccache)
       PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
     dtrace)
--- a/common/autoconf/jdk-version.m4	Fri Dec 16 01:46:00 2016 -0800
+++ b/common/autoconf/jdk-version.m4	Tue Dec 13 02:04:23 2016 +0100
@@ -160,11 +160,10 @@
     fi
   else
     if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then
-      # Default is to calculate a string like this <timestamp>.<username>.<base dir name>
-      timestamp=`$DATE '+%Y-%m-%d-%H%M%S'`
+      # Default is to calculate a string like this 'adhoc.<username>.<base dir name>'
       # Outer [ ] to quote m4.
       [ basedirname=`$BASENAME "$TOPDIR" | $TR -d -c '[a-z][A-Z][0-9].-'` ]
-      VERSION_OPT="$timestamp.$USERNAME.$basedirname"
+      VERSION_OPT="adhoc.$USERNAME.$basedirname"
     fi
   fi
 
--- a/common/autoconf/lib-ffi.m4	Fri Dec 16 01:46:00 2016 -0800
+++ b/common/autoconf/lib-ffi.m4	Tue Dec 13 02:04:23 2016 +0100
@@ -35,6 +35,8 @@
       [specify directory for the libffi include files])])
   AC_ARG_WITH(libffi-lib, [AS_HELP_STRING([--with-libffi-lib],
       [specify directory for the libffi library])])
+  AC_ARG_ENABLE(libffi-bundling, [AS_HELP_STRING([--enable-libffi-bundling],
+      [enable bundling of libffi.so to make the built JDK runnable on more systems])])
 
   if test "x$NEEDS_LIB_FFI" = xfalse; then
     if (test "x${with_libffi}" != x && test "x${with_libffi}" != xno) || \
@@ -52,6 +54,7 @@
     fi
 
     if test "x${with_libffi}" != x; then
+      LIBFFI_LIB_PATH="${with_libffi}/lib"
       LIBFFI_LIBS="-L${with_libffi}/lib -lffi"
       LIBFFI_CFLAGS="-I${with_libffi}/include"
       LIBFFI_FOUND=yes
@@ -61,6 +64,7 @@
       LIBFFI_FOUND=yes
     fi
     if test "x${with_libffi_lib}" != x; then
+      LIBFFI_LIB_PATH="${with_libffi_lib}"
       LIBFFI_LIBS="-L${with_libffi_lib} -lffi"
       LIBFFI_FOUND=yes
     fi
@@ -109,8 +113,65 @@
       HELP_MSG_MISSING_DEPENDENCY([ffi])
       AC_MSG_ERROR([Found libffi but could not link and compile with it. $HELP_MSG])
     fi
+
+    AC_MSG_CHECKING([if libffi should be bundled])
+    if test "x$enable_libffi_bundling" = "x"; then
+      AC_MSG_RESULT([no])
+      ENABLE_LIBFFI_BUNDLING=false
+    elif  test "x$enable_libffi_bundling" = "xno"; then
+      AC_MSG_RESULT([no, forced])
+      ENABLE_LIBFFI_BUNDLING=false
+    elif  test "x$enable_libffi_bundling" = "xyes"; then
+      AC_MSG_RESULT([yes, forced])
+      ENABLE_LIBFFI_BUNDLING=true
+    else
+      AC_MSG_ERROR([Invalid value for --enable-libffi-bundling])
+    fi
+
+    # Find the libffi.so.X to bundle
+    if test "x${ENABLE_LIBFFI_BUNDLING}" = "xtrue"; then
+      AC_MSG_CHECKING([for libffi lib file location])
+      if test "x${LIBFFI_LIB_PATH}" != x; then
+        if test -e ${LIBFFI_LIB_PATH}/libffi.so.?; then
+          LIBFFI_LIB_FILE="${LIBFFI_LIB_PATH}/libffi.so.?"
+        else
+          AC_MSG_ERROR([Could not locate libffi.so.? for bundling in ${LIBFFI_LIB_PATH}])
+        fi
+      else
+        # If we don't have an explicit path, look in a few obvious places
+        if test "x${OPENJDK_TARGET_CPU}" = "xx86"; then
+          if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
+          elif test -e ${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.?"
+          else
+            AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
+          fi
+        elif test "x${OPENJDK_TARGET_CPU}" = "xx86_64"; then
+          if test -e ${SYSROOT}/usr/lib64/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib64/libffi.so.?"
+          elif test -e ${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.?"
+          else
+            AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
+          fi
+        else
+          # Fallback on the default /usr/lib dir
+          if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
+            LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
+          else
+            AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
+          fi
+        fi
+      fi
+      # Make sure the wildcard is evaluated
+      LIBFFI_LIB_FILE="$(ls ${LIBFFI_LIB_FILE})"
+      AC_MSG_RESULT([${LIBFFI_LIB_FILE}])
+    fi
   fi
 
   AC_SUBST(LIBFFI_CFLAGS)
   AC_SUBST(LIBFFI_LIBS)
+  AC_SUBST(ENABLE_LIBFFI_BUNDLING)
+  AC_SUBST(LIBFFI_LIB_FILE)
 ])
--- a/common/autoconf/spec.gmk.in	Fri Dec 16 01:46:00 2016 -0800
+++ b/common/autoconf/spec.gmk.in	Tue Dec 13 02:04:23 2016 +0100
@@ -319,6 +319,8 @@
 ALSA_CFLAGS:=@ALSA_CFLAGS@
 LIBFFI_LIBS:=@LIBFFI_LIBS@
 LIBFFI_CFLAGS:=@LIBFFI_CFLAGS@
+ENABLE_LIBFFI_BUNDLING:=@ENABLE_LIBFFI_BUNDLING@
+LIBFFI_LIB_FILE:=@LIBFFI_LIB_FILE@
 
 PACKAGE_PATH=@PACKAGE_PATH@
 
--- a/common/conf/jib-profiles.js	Fri Dec 16 01:46:00 2016 -0800
+++ b/common/conf/jib-profiles.js	Tue Dec 13 02:04:23 2016 +0100
@@ -346,6 +346,35 @@
     // Generate debug profiles for the open jprt profiles
     profiles = concatObjects(profiles, generateDebugProfiles(common, openOnlyProfiles));
 
+    // Profiles for building the zero jvm variant. These are used for verification
+    // in JPRT.
+    var zeroProfiles = {
+        "linux-x64-zero": {
+            target_os: "linux",
+            target_cpu: "x64",
+            dependencies: concat(common.dependencies, "devkit"),
+            configure_args: concat(common.configure_args,
+                "--with-zlib=system",
+                "--with-jvm-variants=zero",
+                "--enable-libffi-bundling"),
+            default_make_targets: common.default_make_targets
+        },
+
+        "linux-x86-zero": {
+            target_os: "linux",
+            target_cpu: "x86",
+            build_cpu: "x64",
+            dependencies: concat(common.dependencies, "devkit"),
+            configure_args: concat(common.configure_args, common.configure_args_32bit,
+                "--with-zlib=system",
+                "--with-jvm-variants=zero",
+                "--enable-libffi-bundling"),
+            default_make_targets: common.default_make_targets
+        },
+    }
+    profiles = concatObjects(profiles, zeroProfiles);
+    profiles = concatObjects(profiles, generateDebugProfiles(common, zeroProfiles));
+
     // Profiles used to run tests. Used in JPRT.
     var testOnlyProfiles = {
 
@@ -380,7 +409,7 @@
         + (input.build_cpu == "x86" ? "i586" : input.build_cpu);
 
     var devkit_platform_revisions = {
-        linux_x64: "gcc4.9.2-OEL6.4+1.0",
+        linux_x64: "gcc4.9.2-OEL6.4+1.1",
         macosx_x64: "Xcode6.3-MacOSX10.9+1.0",
         solaris_x64: "SS12u4-Solaris11u1+1.0",
         solaris_sparcv9: "SS12u4-Solaris11u1+1.0",
--- a/corba/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/corba/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -390,3 +390,4 @@
 a44b156ae7f06bf41b9bece30df7775e482395dd jdk-9+145
 ecd74b41ab65bf228837b5bdf99690638d55425c jdk-9+146
 dc49e0922a8e4387cbf8670bbe1dc51c9874b74b jdk-9+147
+f95cc86b6ac22ec1ade5d4f825dc7782adeea228 jdk-9+148
--- a/hotspot/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/hotspot/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -550,3 +550,4 @@
 61e7ea56312351657e69198c503a6f7bf865af83 jdk-9+145
 a82cb5350cad96a0b4de496afebe3ded89f27efa jdk-9+146
 132a72c782071cc11ab25cc7c9ee167c3632fea4 jdk-9+147
+5e4e893520ecdbd517c6ed6375f0885664fe62c4 jdk-9+148
--- a/jaxp/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -390,3 +390,4 @@
 71558b38bad786f11350790cef7d2c6409813e91 jdk-9+145
 09eda28b98e4b9cae1d29e94f0cf1a01cc42c207 jdk-9+146
 149559dd882ddca2c78355641a46db9138b12763 jdk-9+147
+c45db75bfe8bc20bb80b4a009ae3f69c9cd2d885 jdk-9+148
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_de.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 06:43:54 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_es.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 09:06:34 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_fr.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 05:13:35 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_it.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 07:02:00 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_ja.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 00:37:07 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_ko.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 02:39:50 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_pt_BR.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 18:01:34 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_sv.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 01:57:20 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_zh_CN.java /st_wptg_1.8.0.0.0jdk/3 2013/11/11 11:39:28 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XSLTErrorResources_zh_TW.java /st_wptg_1.9.0.0.0jdk/2 2016/04/11 20:46:43 gmolloy Exp $
- */
 package com.sun.org.apache.xalan.internal.res;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_de.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 06:43:54 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "Ung\u00FCltiger URI \"{0}\"."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: CatalogResolver ist mit dem Katalog \"{0}\" aktiviert, eine CatalogException wird jedoch zur\u00FCckgegeben."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "Zyklisches import/include. Stylesheet \"{0}\" bereits geladen."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "Die untergeordneten Elemente des xsl:import-Elements m\u00FCssen vor allen anderen untergeordneten Elementen eines xsl:stylesheet-Elements stehen, einschlie\u00DFlich eventueller untergeordneter Elemente des xsl:include-Elements."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_es.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 05:09:25 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI ''{0}'' no v\u00E1lido."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: CatalogResolver est\u00E1 activado con el cat\u00E1logo \"{0}\", pero se ha devuelto una excepci\u00F3n CatalogException."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "Import/include circular. La hoja de estilo ''{0}'' ya se ha cargado."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "Los secundarios del elemento xsl:import deben preceder al resto de secundarios de elementos de un elemento xsl:stylesheet, incluidos los secundarios de elementos xsl:include."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_fr.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 05:13:35 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI ''{0}'' non valide."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001 : le CatalogResolver est activ\u00E9 avec le catalogue \"{0}\", mais une exception CatalogException est renvoy\u00E9e."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "Op\u00E9ration import/include circulaire. La feuille de style ''{0}'' est d\u00E9j\u00E0 charg\u00E9e."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "Les enfants d'\u00E9l\u00E9ment xsl:import doivent pr\u00E9c\u00E9der tous les autres enfants d'\u00E9l\u00E9ment d'un \u00E9l\u00E9ment xsl:stylesheet, y compris tout enfant d'\u00E9l\u00E9ment xsl:include."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_it.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 03:53:19 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI ''{0}'' non valido."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: il CatalogResolver \u00E8 abilitato con il catalogo \"{0}\", ma viene restituita una CatalogException."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "Importazione/inclusione circolare. Il foglio di stile ''{0}'' \u00E8 gi\u00E0 stato caricato."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "Gli elementi figlio dell'elemento xsl:import devono precedere tutti gli elementi figlio di xsl:stylesheet, inclusi eventuali elementi figlio di xsl:include."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_ja.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 00:37:07 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI ''{0}''\u304C\u7121\u52B9\u3067\u3059\u3002"},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: CatalogResolver\u306F\u30AB\u30BF\u30ED\u30B0\"{0}\"\u3067\u6709\u52B9\u3067\u3059\u304C\u3001CatalogException\u304C\u8FD4\u3055\u308C\u307E\u3059\u3002"},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "\u30A4\u30F3\u30DD\u30FC\u30C8\u307E\u305F\u306F\u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u304C\u5FAA\u74B0\u3057\u3066\u3044\u307E\u3059\u3002\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8''{0}''\u306F\u3059\u3067\u306B\u30ED\u30FC\u30C9\u3055\u308C\u3066\u3044\u307E\u3059\u3002"},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "xsl:import\u8981\u7D20\u306E\u5B50\u306F\u3001xsl:stylesheet\u8981\u7D20\u306E\u4ED6\u306E\u3059\u3079\u3066\u306E\u8981\u7D20\u306E\u5B50(\u3059\u3079\u3066\u306Exsl:include\u8981\u7D20\u306E\u5B50\u3092\u542B\u3080)\u3088\u308A\u524D\u306B\u7F6E\u304F\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002"},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_ko.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 02:39:51 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI ''{0}''\uC774(\uAC00) \uBD80\uC801\uD569\uD569\uB2C8\uB2E4."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: CatalogResolver\uAC00 \"{0}\" \uCE74\uD0C8\uB85C\uADF8\uC5D0 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uB418\uC5C8\uC9C0\uB9CC CatalogException\uC774 \uBC18\uD658\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "\uC21C\uD658 import/include\uC785\uB2C8\uB2E4. ''{0}'' \uC2A4\uD0C0\uC77C\uC2DC\uD2B8\uAC00 \uC774\uBBF8 \uB85C\uB4DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "xsl:import \uC694\uC18C \uD558\uC704\uB294 xsl:include \uC694\uC18C \uD558\uC704\uB97C \uD3EC\uD568\uD574 xsl:stylesheet \uC694\uC18C\uC758 \uBAA8\uB4E0 \uB2E4\uB978 \uC694\uC18C \uD558\uC704 \uC55E\uC5D0 \uC640\uC57C \uD569\uB2C8\uB2E4."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_pt_BR.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 18:01:34 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI inv\u00E1lido ''{0}''."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: O CatalogResolver foi ativado com o cat\u00E1logo \"{0}\", mas uma CatalogException foi retornada."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "Import/Include circular. Folha de estilos ''{0}'' j\u00E1 carregada."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "Os filhos do elemento xsl:import devem preceder todos os outros filhos de um elemento xsl:stylesheet, inclusive quaisquer filhos do elemento xsl:include."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_sv.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 01:57:20 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "Ogiltig URI ''{0}''."},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: CatalogResolver \u00E4r aktiverat med katalogen \"{0}\", men ett CatalogException returneras."},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "Cirkul\u00E4r import/include. Formatmallen ''{0}'' har redan laddats."},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "Underordnade till xsl:import-elementet m\u00E5ste komma f\u00F6re alla andra underordnade till element f\u00F6r ett xsl:stylesheet-element, inklusive alla underordnade till xsl:include-elementet."},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_zh_CN.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 05:10:27 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "URI ''{0}'' \u65E0\u6548\u3002"},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: \u5DF2\u5BF9\u76EE\u5F55 \"{0}\" \u542F\u7528 CatalogResolver, \u4F46\u8FD4\u56DE\u4E86 CatalogException\u3002"},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "\u5FAA\u73AF import/include\u3002\u5DF2\u52A0\u8F7D\u6837\u5F0F\u8868 ''{0}''\u3002"},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "xsl:import \u5143\u7D20\u5B50\u7EA7\u5FC5\u987B\u4F4D\u4E8E xsl:stylesheet \u5143\u7D20\u7684\u6240\u6709\u5176\u4ED6\u5143\u7D20\u5B50\u7EA7 (\u5305\u62EC\u4EFB\u4F55 xsl:include \u5143\u7D20\u5B50\u7EA7) \u4E4B\u524D\u3002"},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_zh_TW.java /st_wptg_1.9.0.0.0jdk/2 2016/04/11 20:46:43 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
 
@@ -173,6 +170,13 @@
         "\u7121\u6548\u7684 URI ''{0}''\u3002"},
 
         /*
+         * Note to translators:  This message is displayed when the URI
+         * mentioned in the substitution text is not well-formed syntactically.
+         */
+        {ErrorMsg.CATALOG_EXCEPTION,
+        "JAXP08090001: CatalogResolver \u5DF2\u555F\u7528\u76EE\u9304 \"{0}\"\uFF0C\u4F46\u50B3\u56DE CatalogException\u3002"},
+
+        /*
          * Note to translators:  The file or URI named in the substitution text
          * exists but could not be opened.
          */
@@ -269,6 +273,13 @@
         "\u5FAA\u74B0\u532F\u5165/\u5305\u542B\u3002\u5DF2\u7D93\u8F09\u5165\u6A23\u5F0F\u8868 ''{0}''\u3002"},
 
         /*
+         * Note to translators:  "xsl:import" and "xsl:include" are keywords that
+         * should not be translated.
+         */
+        {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+        "xsl:import \u5143\u7D20\u5B50\u9805\u5FC5\u9808\u5728 xsl:stylesheet \u5143\u7D20\u7684\u6240\u6709\u5176\u4ED6\u5143\u7D20\u5B50\u9805\u4E4B\u524D\uFF0C\u5305\u62EC\u4EFB\u4F55 xsl:include \u5143\u7D20\u5B50\u9805\u3002"},
+
+        /*
          * Note to translators:  A result-tree fragment is a portion of a
          * resulting XML document represented as a tree.  "<xsl:sort>" is a
          * keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_de.java,v 1.2.4.1 2005/09/14 05:13:15 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_es.java,v 1.2.4.1 2005/09/14 05:14:39 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_fr.java,v 1.2.4.1 2005/09/14 05:15:37 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_it.java,v 1.2.4.1 2005/09/14 05:22:16 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_ja.java,v 1.2.4.1 2005/09/14 05:46:36 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_ko.java,v 1.2.4.1 2005/09/14 05:48:33 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_pt_BR.java /st_wptg_1.8.0.0.0jdk/2 2013/09/11 12:46:53 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_sv.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 01:57:20 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_zh_CN.java /st_wptg_1.8.0.0.0jdk/3 2013/11/11 11:39:28 gmolloy Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: ErrorMessages_zh_TW.java,v 1.2.4.1 2005/09/14 06:56:12 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.runtime;
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: Der Parser hat mehr als {0} Entityerweiterungen in diesem Dokument gefunden. Dies ist der von JDK vorgeschriebene Grenzwert.
         ElementAttributeLimit=JAXP00010002: Element "{0}" hat mehr als {1} Attribute. "{1}" ist der von JDK vorgeschriebene Grenzwert.
         MaxEntitySizeLimit=JAXP00010003: Die L\u00E4nge von Entity "{0}" ist "{1}" und \u00FCberschreitet den Grenzwert "{2}", der von "{3}" festgelegt wurde.
-        TotalEntitySizeLimit=JAXP00010004: Die akkumulierte Gr\u00F6\u00DFe von Entitys ist "{1}" und \u00FCberschreitet den Grenzwert "{2}", der von "{3}" festgelegt wurde.
+        TotalEntitySizeLimit=JAXP00010004: Die akkumulierte Gr\u00F6\u00DFe von Entitys ist "{0}" und \u00FCberschreitet den Grenzwert "{1}", der von "{2}" festgelegt wurde.
         MaxXMLNameLimit=JAXP00010005: Die L\u00E4nge von Entity "{0}" ist "{1}" und \u00FCberschreitet den Grenzwert "{2}", der von "{3}" festgelegt wurde.
         MaxElementDepthLimit=JAXP00010006: Die Tiefe von Element "{0}" ist "{1}" und \u00FCberschreitet den Grenzwert "{2}", der von "{3}" festgelegt wurde.
+        EntityReplacementLimit=JAXP00010007: Die Gesamtanzahl von Knoten in Entityreferenzen betr\u00E4gt "{0}". Das liegt \u00FCber dem von "{2}" festgelegten Grenzwert "{1}".
 
+# Catalog 09
+        CatalogException=JAXP00090001: CatalogResolver ist mit dem Katalog "{0}" aktiviert, eine CatalogException wird jedoch zur\u00FCckgegeben.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: el analizador ha encontrado m\u00E1s de "{0}"ampliaciones de entidad en este documento; \u00E9ste es el l\u00EDmite impuesto por el JDK.
         ElementAttributeLimit=JAXP00010002: el elemento "{0}" tiene m\u00E1s de "{1}" atributos, "{1}" es el l\u00EDmite impuesto por el JDK.
         MaxEntitySizeLimit=JAXP00010003: la longitud de la entidad "{0}" es "{1}", que excede el l\u00EDmite de "{2}" que ha definido "{3}".
-        TotalEntitySizeLimit=JAXP00010004: el tama\u00F1o acumulado de las entidades es "{1}" y excede el l\u00EDmite de "{2}" definido por "{3}".
+        TotalEntitySizeLimit=JAXP00010004: el tama\u00F1o acumulado de las entidades es "{0}" y excede el l\u00EDmite de "{1}" definido por "{2}".
         MaxXMLNameLimit=JAXP00010005: la longitud de la entidad "{0}" es "{1}" y excede el l\u00EDmite de "{2}" definido por "{3}".
         MaxElementDepthLimit=JAXP00010006: El elemento "{0}" tiene una profundidad de "{1}" que excede el l\u00EDmite "{2}" definido por "{3}".
+        EntityReplacementLimit=JAXP00010007: El n\u00FAmero total de nodos en las referencias de entidad es de "{0}" que supera el l\u00EDmite de "{1}" definido por "{2}".
 
+# Catalog 09
+        CatalogException=JAXP00090001: CatalogResolver est\u00E1 activado con el cat\u00E1logo "{0}", pero se ha devuelto una excepci\u00F3n CatalogException.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001 : L''analyseur a rencontr\u00E9 plus de "{0}" d\u00E9veloppements d''entit\u00E9 dans ce document. Il s''agit de la limite impos\u00E9e par le JDK.
         ElementAttributeLimit=JAXP00010002 : L''\u00E9l\u00E9ment "{0}" a plus de "{1}" attributs. "{1}" est la limite impos\u00E9e par le JDK.
         MaxEntitySizeLimit=JAXP00010003 : La longueur de l''entit\u00E9 "{0}" est de "{1}". Cette valeur d\u00E9passe la limite de "{2}" d\u00E9finie par "{3}".
-        TotalEntitySizeLimit=JAXP00010004 : La taille cumul\u00E9e des entit\u00E9s est "{1}" et d\u00E9passe la limite de "{2}" d\u00E9finie par "{3}".
+        TotalEntitySizeLimit=JAXP00010004 : La taille cumul\u00E9e des entit\u00E9s est "{0}" et d\u00E9passe la limite de "{1}" d\u00E9finie par "{2}".
         MaxXMLNameLimit=JAXP00010005 : La longueur de l''entit\u00E9 "{0}" est de "{1}". Cette valeur d\u00E9passe la limite de "{2}" d\u00E9finie par "{3}".
         MaxElementDepthLimit=JAXP00010006 : l''\u00E9l\u00E9ment "{0}" a une profondeur de "{1}" qui d\u00E9passe la limite de "{2}" d\u00E9finie par "{3}".
+        EntityReplacementLimit=JAXP00010007 : Le nombre total de noeuds dans les r\u00E9f\u00E9rences d''entit\u00E9 est "{0}", soit plus que la limite de "{1}" d\u00E9finie par "{2}".
 
+# Catalog 09
+        CatalogException=JAXP00090001 : le CatalogResolver est activ\u00E9 avec le catalogue "{0}", mais une exception CatalogException est renvoy\u00E9e.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: il parser ha rilevato pi\u00F9 "{0}" espansioni di entit\u00E0 nel documento. Questo \u00E8 il limite imposto dal kit JDK.
         ElementAttributeLimit=JAXP00010002: l''elemento "{0}" contiene pi\u00F9 di "{1}" attributi. "{1}" \u00E8 il limite imposto dal kit JDK.
         MaxEntitySizeLimit=JAXP00010003: la lunghezza dell''entit\u00E0 "{0}" \u00E8 "{1}". Tale valore supera il limite "{2}" definito da "{3}".
-        TotalEntitySizeLimit=JAXP00010004: le dimensioni accumulate delle entit\u00E0 sono pari a "{1}". Tale valore supera il limite "{2}" definito da "{3}".
+        TotalEntitySizeLimit=JAXP00010004: le dimensioni accumulate delle entit\u00E0 sono pari a "{0}". Tale valore supera il limite "{1}" definito da "{2}".
         MaxXMLNameLimit=JAXP00010005: la lunghezza dell''entit\u00E0 "{0}" \u00E8 "{1}". Tale valore supera il limite "{2}" definito da "{3}".
         MaxElementDepthLimit=JAXP00010006: la profondit\u00E0 dell''elemento "{0}" \u00E8 "{1}". Tale valore supera il limite "{2}" definito da "{3}".
+        EntityReplacementLimit=JAXP00010007: il numero totale di nodi nei riferimenti entit\u00E0 \u00E8 "{0}". Tale valore supera il limite di "{1}" impostato da "{2}".
 
+# Catalog 09
+        CatalogException=JAXP00090001: il CatalogResolver \u00E8 abilitato con il catalogo "{0}", ma viene restituita una CatalogException.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: \u30D1\u30FC\u30B5\u30FC\u306B\u3088\u3063\u3066\u3001\u3053\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5185\u3067"{0}"\u3092\u8D85\u3048\u308B\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u62E1\u5F35\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\u3053\u308C\u306F\u3001JDK\u306B\u3088\u308B\u5236\u9650\u3067\u3059\u3002
         ElementAttributeLimit=JAXP00010002: \u8981\u7D20"{0}"\u306B"{1}"\u3092\u8D85\u3048\u308B\u5C5E\u6027\u304C\u5B58\u5728\u3057\u307E\u3059\u3002"{1}"\u306F\u3001JDK\u306B\u3088\u308B\u5236\u9650\u3067\u3059\u3002
         MaxEntitySizeLimit=JAXP00010003: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3"{0}"\u306E\u9577\u3055\u306F"{1}"\u3067\u3001"{3}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{2}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002
-        TotalEntitySizeLimit=JAXP00010004: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u306E\u7D2F\u7A4D\u30B5\u30A4\u30BA"{1}"\u306F\u3001"{3}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{2}"\u3092\u8D85\u3048\u307E\u3057\u305F\u3002
+        TotalEntitySizeLimit=JAXP00010004: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u306E\u7D2F\u7A4D\u30B5\u30A4\u30BA"{0}"\u306F\u3001"{2}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{1}"\u3092\u8D85\u3048\u307E\u3057\u305F\u3002
         MaxXMLNameLimit=JAXP00010005: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3"{0}"\u306E\u9577\u3055\u306F"{1}"\u3067\u3001"{3}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{2}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002
         MaxElementDepthLimit=JAXP00010006: \u8981\u7D20"{0}"\u306E\u6DF1\u3055\u306F"{1}"\u3067\u3001"{3}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{2}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002
+        EntityReplacementLimit=JAXP00010007: \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\u306E\u5408\u8A08\u30CE\u30FC\u30C9\u6570\u306F"{0}"\u3067\u3001"{2}"\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u5236\u9650"{1}"\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002
 
+# Catalog 09
+        CatalogException=JAXP00090001: CatalogResolver\u306F\u30AB\u30BF\u30ED\u30B0"{0}"\u3067\u6709\u52B9\u3067\u3059\u304C\u3001CatalogException\u304C\u8FD4\u3055\u308C\u307E\u3059\u3002
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: \uAD6C\uBB38 \uBD84\uC11D\uAE30\uAC00 \uC774 \uBB38\uC11C\uC5D0\uC11C "{0}"\uAC1C\uB97C \uCD08\uACFC\uD558\uB294 \uC5D4\uD2F0\uD2F0 \uD655\uC7A5\uC744 \uBC1C\uACAC\uD588\uC2B5\uB2C8\uB2E4. \uC774\uB294 JDK\uC5D0\uC11C \uC801\uC6A9\uD558\uB294 \uC81C\uD55C\uC785\uB2C8\uB2E4.
         ElementAttributeLimit=JAXP00010002:  "{0}" \uC694\uC18C\uC5D0 "{1}"\uAC1C\uB97C \uCD08\uACFC\uD558\uB294 \uC18D\uC131\uC774 \uC788\uC2B5\uB2C8\uB2E4. "{1}"\uC740(\uB294) JDK\uC5D0\uC11C \uC801\uC6A9\uD558\uB294 \uC81C\uD55C\uC785\uB2C8\uB2E4.
         MaxEntitySizeLimit=JAXP00010003: "{0}" \uC5D4\uD2F0\uD2F0\uC758 \uAE38\uC774\uAC00 "{3}"\uC5D0\uC11C \uC124\uC815\uB41C "{2}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{1}"\uC785\uB2C8\uB2E4.
-        TotalEntitySizeLimit=JAXP00010004: \uC5D4\uD2F0\uD2F0\uC758 \uB204\uC801 \uD06C\uAE30\uAC00 "{3}"\uC5D0\uC11C \uC124\uC815\uD55C "{2}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{1}"\uC785\uB2C8\uB2E4.
+        TotalEntitySizeLimit=JAXP00010004: \uC5D4\uD2F0\uD2F0\uC758 \uB204\uC801 \uD06C\uAE30\uAC00 "{2}"\uC5D0\uC11C \uC124\uC815\uD55C "{1}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{0}"\uC785\uB2C8\uB2E4.
         MaxXMLNameLimit=JAXP00010005: "{0}" \uC5D4\uD2F0\uD2F0\uC758 \uAE38\uC774\uAC00 "{3}"\uC5D0\uC11C \uC124\uC815\uD55C "{2}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{1}"\uC785\uB2C8\uB2E4.
         MaxElementDepthLimit=JAXP00010006: "{0}" \uC694\uC18C\uC758 \uAE4A\uC774\uAC00 "{3}"\uC5D0\uC11C \uC124\uC815\uB41C "{2}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{1}"\uC785\uB2C8\uB2E4.
+        EntityReplacementLimit=JAXP00010007: \uC5D4\uD2F0\uD2F0 \uCC38\uC870\uC758 \uCD1D \uB178\uB4DC \uC218\uAC00 "{2}"\uC5D0\uC11C \uC124\uC815\uD55C "{1}" \uC81C\uD55C\uC744 \uCD08\uACFC\uD558\uB294 "{0}"\uC785\uB2C8\uB2E4.
 
+# Catalog 09
+        CatalogException=JAXP00090001: CatalogResolver\uAC00 "{0}" \uCE74\uD0C8\uB85C\uADF8\uC5D0 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uB418\uC5C8\uC9C0\uB9CC CatalogException\uC774 \uBC18\uD658\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: O parser detectou mais de "{0}" expans\u00F5es da entidade neste documento. Este \u00E9 o limite imposto pelo JDK.
         ElementAttributeLimit=JAXP00010002: o elemento "{0}" tem mais de "{1}" atributos. "{1}" \u00E9 o limite imposto pelo JDK.
         MaxEntitySizeLimit=JAXP00010003: o tamanho da entidade "{0}" \u00E9 "{1}", o que excede o limite de "{2}" definido por "{3}".
-        TotalEntitySizeLimit=JAXP00010004: o tamanho acumulado de entidades \u00E9 "{1}", o que excedeu o limite de "{2}" definido por "{3}".
+        TotalEntitySizeLimit=JAXP00010004: o tamanho acumulado de entidades \u00E9 "{0}", o que excedeu o limite de "{1}" definido por "{2}".
         MaxXMLNameLimit=JAXP00010005: o tamanho da entidade "{0}" \u00E9 "{1}", o que excede o limite de "{2}" definido por "{3}".
         MaxElementDepthLimit=JAXP00010006: o elemento "{0}" tem uma profundidade de "{1}" que excede o limite de "{2}" definido por "{3}".
+        EntityReplacementLimit=JAXP00010007: O n\u00FAmero total de n\u00F3s nas refer\u00EAncias da entidade \u00E9 de "{0}", o que est\u00E1 acima do limite de "{1}" definido por "{2}".
 
+# Catalog 09
+        CatalogException=JAXP00090001: O CatalogResolver foi ativado com o cat\u00E1logo "{0}", mas uma CatalogException foi retornada.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: Parsern har p\u00E5tr\u00E4ffat fler \u00E4n "{0}" enhetstill\u00E4gg i dokumentet - gr\u00E4nsv\u00E4rdet f\u00F6r JDK har uppn\u00E5tts.
         ElementAttributeLimit=JAXP00010002:  Elementet "{0}" har fler \u00E4n "{1}" attribut, "{1}" \u00E4r gr\u00E4nsv\u00E4rdet f\u00F6r JDK.
         MaxEntitySizeLimit=JAXP00010003: L\u00E4ngden p\u00E5 enheten "{0}" \u00E4r "{1}" som \u00F6verskriver gr\u00E4nsv\u00E4rdet p\u00E5 "{2}" som anges av "{3}".
-        TotalEntitySizeLimit=JAXP00010004: Den ackumulerade storleken f\u00F6r enheter \u00E4r "{1}", vilket \u00F6verskrider gr\u00E4nsv\u00E4rdet "{2}" som anges av "{3}".
+        TotalEntitySizeLimit=JAXP00010004: Den ackumulerade storleken f\u00F6r enheter \u00E4r "{0}", vilket \u00F6verskrider gr\u00E4nsv\u00E4rdet "{1}" som anges av "{2}".
         MaxXMLNameLimit=JAXP00010005: L\u00E4ngden p\u00E5 enheten "{0}" \u00E4r "{1}", vilket \u00F6verskrider gr\u00E4nsv\u00E4rdet "{2}" som anges av "{3}".
         MaxElementDepthLimit=JAXP00010006: Elementet "{0}" har djupet "{1}" vilket \u00E4r st\u00F6rre \u00E4n gr\u00E4nsen "{2}" som anges av "{3}".
+        EntityReplacementLimit=JAXP00010007: Det totala antalet noder i enhetsreferenser \u00E4r "{0}", vilket \u00E4r \u00F6ver gr\u00E4nsen "{1}" som har angetts av "{2}".
 
+# Catalog 09
+        CatalogException=JAXP00090001: CatalogResolver \u00E4r aktiverat med katalogen "{0}", men ett CatalogException returneras.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: \u89E3\u6790\u5668\u5728\u6B64\u6587\u6863\u4E2D\u9047\u5230\u591A\u4E2A "{0}" \u5B9E\u4F53\u6269\u5C55; \u8FD9\u662F JDK \u65BD\u52A0\u7684\u9650\u5236\u3002
         ElementAttributeLimit=JAXP00010002: \u5143\u7D20 "{0}" \u5177\u6709\u591A\u4E2A "{1}" \u5C5E\u6027, "{1}" \u662F JDK \u65BD\u52A0\u7684\u9650\u5236\u3002
         MaxEntitySizeLimit=JAXP00010003: \u5B9E\u4F53 "{0}" \u7684\u957F\u5EA6\u4E3A "{1}", \u8D85\u8FC7\u4E86 "{3}" \u8BBE\u7F6E\u7684 "{2}" \u9650\u5236\u3002
-        TotalEntitySizeLimit=JAXP00010004: \u5B9E\u4F53\u7684\u7D2F\u8BA1\u5927\u5C0F\u4E3A "{1}", \u8D85\u8FC7\u4E86 "{3}" \u8BBE\u7F6E\u7684 "{2}" \u9650\u5236\u3002
+        TotalEntitySizeLimit=JAXP00010004: \u5B9E\u4F53\u7684\u7D2F\u8BA1\u5927\u5C0F\u4E3A "{0}", \u8D85\u8FC7\u4E86 "{2}" \u8BBE\u7F6E\u7684 "{1}" \u9650\u5236\u3002
         MaxXMLNameLimit=JAXP00010005: \u5B9E\u4F53 "{0}" \u7684\u957F\u5EA6\u4E3A "{1}", \u8D85\u8FC7\u4E86 "{3}" \u8BBE\u7F6E\u7684 "{2}" \u9650\u5236\u3002
         MaxElementDepthLimit=JAXP00010006: \u5143\u7D20 "{0}" \u7684\u6DF1\u5EA6 "{1}" \u8D85\u8FC7\u4E86 "{3}" \u8BBE\u7F6E\u7684\u9650\u5236 "{2}"\u3002
+        EntityReplacementLimit=JAXP00010007: \u5B9E\u4F53\u5F15\u7528\u4E2D\u7684\u8282\u70B9\u603B\u6570\u4E3A "{0}", \u8D85\u8FC7\u4E86 "{2}" \u8BBE\u7F6E\u7684\u9650\u5236 "{1}"\u3002
 
+# Catalog 09
+        CatalogException=JAXP00090001: \u5DF2\u5BF9\u76EE\u5F55 "{0}" \u542F\u7528 CatalogResolver, \u4F46\u8FD4\u56DE\u4E86 CatalogException\u3002
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -298,7 +298,10 @@
         EntityExpansionLimit=JAXP00010001: \u5256\u6790\u5668\u5728\u6B64\u6587\u4EF6\u4E2D\u9047\u5230 "{0}" \u500B\u4EE5\u4E0A\u7684\u5BE6\u9AD4\u64F4\u5145; \u9019\u662F JDK \u6240\u898F\u5B9A\u7684\u9650\u5236\u3002
         ElementAttributeLimit=JAXP00010002: \u5143\u7D20 "{0}" \u5177\u6709\u8D85\u904E "{1}" \u500B\u4EE5\u4E0A\u7684\u5C6C\u6027\uFF0C"{1}" \u662F JDK \u6240\u898F\u5B9A\u7684\u9650\u5236\u3002
         MaxEntitySizeLimit=JAXP00010003: \u5BE6\u9AD4 "{0}" \u7684\u9577\u5EA6\u70BA "{1}"\uFF0C\u8D85\u904E "{3}" \u6240\u8A2D\u5B9A\u7684 "{2}" \u9650\u5236\u3002
-        TotalEntitySizeLimit=JAXP00010004: \u5BE6\u9AD4\u7684\u7D2F\u7A4D\u5927\u5C0F\u70BA "{1}"\uFF0C\u8D85\u904E "{3}" \u6240\u8A2D\u5B9A\u7684 "{2}" \u9650\u5236\u3002
+        TotalEntitySizeLimit=JAXP00010004: \u5BE6\u9AD4\u7684\u7D2F\u7A4D\u5927\u5C0F\u70BA "{0}"\uFF0C\u8D85\u904E "{2}" \u6240\u8A2D\u5B9A\u7684 "{1}" \u9650\u5236\u3002
         MaxXMLNameLimit=JAXP00010005: \u5BE6\u9AD4 "{0}" \u7684\u9577\u5EA6\u70BA "{1}"\uFF0C\u8D85\u904E "{3}" \u6240\u8A2D\u5B9A\u7684 "{2}" \u9650\u5236\u3002
         MaxElementDepthLimit=JAXP00010006: \u5143\u7D20 "{0}" \u7684\u6DF1\u5EA6\u70BA "{1}"\uFF0C\u8D85\u904E "{3}" \u8A2D\u5B9A\u7684 "{2}" \u9650\u5236\u3002
+        EntityReplacementLimit=JAXP00010007: \u5BE6\u9AD4\u53C3\u7167\u4E2D\u7684\u7BC0\u9EDE\u7E3D\u6578\u70BA "{0}"\uFF0C\u8D85\u904E "{2}" \u6240\u8A2D\u5B9A\u7684 "{1}" \u9650\u5236\u3002
 
+# Catalog 09
+        CatalogException=JAXP00090001: CatalogResolver \u5DF2\u555F\u7528\u76EE\u9304 "{0}"\uFF0C\u4F46\u50B3\u56DE CatalogException\u3002
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_de.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_de.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=Ung\u00FCltiger Quantifizierer. Eine Stelle oder '}' wird erwartet.
 parser.quantifier.4=Ung\u00FCltiger Quantifizierer. Mindestmenge muss <= Maximalmenge sein.
 parser.quantifier.5=Ung\u00FCltiger Quantifizierer. Ein Mengenwert\u00FCberlauf.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_es.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_es.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=Cuantificador no v\u00E1lido. Se esperaba un d\u00EDgito o '}'.
 parser.quantifier.4=Cuantificador no v\u00E1lido. Una cantidad m\u00EDnima debe ser <= una cantidad m\u00E1xima.
 parser.quantifier.5=Cuantificador no v\u00E1lido. Desbordamiento de un valor de cantidad.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_fr.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_fr.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=Quantificateur non valide. Un chiffre ou une accolade ('}') est attendu.
 parser.quantifier.4=Quantificateur non valide. Une quantit\u00E9 minimale doit \u00EAtre <= une quantit\u00E9 maximale.
 parser.quantifier.5=Quantificateur non valide. D\u00E9bordement de la valeur de quantit\u00E9.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_it.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_it.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=Quantificatore non valido. \u00C8 prevista una cifra o '}'.
 parser.quantifier.4=Quantificatore non valido.Una quantit\u00E0 minima deve essere <= di una quantit\u00E0 massima.
 parser.quantifier.5=Quantificatore non valido. Overflow del valore di quantit\u00E0.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=\u7121\u52B9\u306A\u6570\u91CF\u8A5E\u3067\u3059\u3002\u6570\u5B57\u307E\u305F\u306F'}'\u304C\u5FC5\u8981\u3067\u3059\u3002
 parser.quantifier.4=\u7121\u52B9\u306A\u6570\u91CF\u8A5E\u3067\u3059\u3002\u6700\u5C0F\u6570\u91CF\u306F\u6700\u5927\u6570\u91CF\u4EE5\u4E0B\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
 parser.quantifier.5=\u7121\u52B9\u306A\u6570\u91CF\u8A5E\u3067\u3059\u3002\u6570\u91CF\u5024\u304C\u30AA\u30FC\u30D0\u30FC\u30D5\u30ED\u30FC\u3057\u3066\u3044\u307E\u3059\u3002
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_ko.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_ko.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=\uC218\uB7C9\uC0AC\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. \uC22B\uC790\uB098 '}'\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.
 parser.quantifier.4=\uC218\uB7C9\uC0AC\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. \uCD5C\uC18C \uC218\uB7C9\uC740 \uCD5C\uB300 \uC218\uB7C9 \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4.
 parser.quantifier.5=\uC218\uB7C9\uC0AC\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. \uC218\uB7C9 \uAC12 \uC624\uBC84\uD50C\uB85C\uC6B0\uC785\uB2C8\uB2E4.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_pt_BR.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_pt_BR.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=Quantificador inv\u00E1lido. \u00C9 esperado um d\u00EDgito ou '}'.
 parser.quantifier.4=Quantificador inv\u00E1lido. Uma quantidade m\u00EDnima deve ser <= uma quantidade m\u00E1xima.
 parser.quantifier.5=Quantificador inv\u00E1lido. Um overflow do valor de quantidade.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_sv.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_sv.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=Ogiltig kvantifierare. En siffra eller '}' f\u00F6rv\u00E4ntas.
 parser.quantifier.4=Ogiltig kvantifierare. En minkvantitet m\u00E5ste vara <= en maxkvantitet.
 parser.quantifier.5=Ogiltig kvantifierare. Ett kvantitetsv\u00E4rdesspill.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=\u9650\u5B9A\u7B26\u65E0\u6548\u3002\u5E94\u4E3A\u6570\u5B57\u6216 '}'\u3002
 parser.quantifier.4=\u9650\u5B9A\u7B26\u65E0\u6548\u3002\u6700\u5C0F\u6570\u91CF\u5FC5\u987B\u5C0F\u4E8E\u7B49\u4E8E\u6700\u5927\u6570\u91CF\u3002
 parser.quantifier.5=\u9650\u5B9A\u7B26\u65E0\u6548\u3002\u6570\u91CF\u503C\u6EA2\u51FA\u3002
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_zh_TW.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message_zh_TW.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -62,5 +62,3 @@
 parser.quantifier.3=\u7121\u6548\u7684\u6578\u91CF\u8A5E. \u9810\u671F\u61C9\u70BA\u6578\u5B57\u6216 '}'.
 parser.quantifier.4=\u7121\u6548\u7684\u6578\u91CF\u8A5E. \u6700\u5C0F\u6578\u91CF\u5FC5\u9808\u5C0F\u65BC\u6216\u7B49\u65BC\u6700\u5927\u6578\u91CF.
 parser.quantifier.5=\u7121\u6548\u7684\u6578\u91CF\u8A5E. \u6578\u91CF\u503C\u6EA2\u4F4D.
-null
-null
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_de.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 04:56:10 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_es.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 09:06:34 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_fr.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 07:05:15 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_it.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 07:02:00 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_ja.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 00:37:07 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_ko.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 02:39:51 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_pt_BR.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 18:01:34 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_sv.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 01:57:20 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_zh_CN.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 05:10:27 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XMLErrorResources_zh_TW.java /st_wptg_1.8.0.0.0jdk/2 2013/09/14 02:16:34 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.res;
 
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_de.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 06:43:54 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_es.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 05:09:25 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_fr.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 05:13:35 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_it.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 03:53:19 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_ja.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 00:37:07 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_ko.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 02:39:51 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_pt_BR.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 18:01:34 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_sv.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 01:57:20 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_zh_CN.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 05:10:27 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -19,9 +19,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: SerializerMessages_zh_TW.java /st_wptg_1.9.0.0.0jdk/2 2016/04/11 20:46:43 gmolloy Exp $
- */
 package com.sun.org.apache.xml.internal.serializer.utils;
 
 import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_de.java /st_wptg_1.9.0.0.0jdk/2 2016/04/13 06:43:54 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "document()-Funktionsimplementierung wurde durch com.sun.org.apache.xalan.internal.xslt.FuncDocument ersetzt."},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "Der Kontext darf nicht Null sein, wenn der Vorgang kontextabh\u00E4ngig ist."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "Kontext hat kein Eigent\u00FCmerdokument."},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_es.java /st_wptg_1.8.0.0.0jdk/2 2013/09/16 09:06:34 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "La implantaci\u00F3n de la funci\u00F3n document() se ha sustituido por com.sun.org.apache.xalan.internal.xslt.FuncDocument!"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "El contexto no puede ser nulo si la operaci\u00F3n depende del contexto."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "El contexto no tiene un documento de propietario."},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_fr.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 05:13:35 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "L'impl\u00E9mentation de la fonction document() a \u00E9t\u00E9 remplac\u00E9e par com.sun.org.apache.xalan.internal.xslt.FuncDocument."},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "Le contexte ne peut pas \u00EAtre NULL lorsque l'op\u00E9ration en d\u00E9pend."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "le contexte ne poss\u00E8de pas de document propri\u00E9taire."},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_it.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 03:53:19 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "L'implementazione della funzione document() \u00E8 stata sostituita da com.sun.org.apache.xalan.internal.xslt.FuncDocument."},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "Il contesto non pu\u00F2 essere nullo quando l'operazione dipende dal contesto."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "il contesto non dispone di un documento proprietario."},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_ja.java /st_wptg_1.8.0.0.0jdk/2 2013/09/12 17:39:58 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "document()\u95A2\u6570\u306E\u5B9F\u88C5\u306Fcom.sun.org.apache.xalan.internal.xslt.FuncDocument\u306B\u3088\u3063\u3066\u7F6E\u63DB\u3055\u308C\u307E\u3057\u305F\u3002"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "\u64CD\u4F5C\u304C\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306B\u4F9D\u5B58\u3057\u3066\u3044\u308B\u5834\u5408\u3001\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092null\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002"},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306B\u6240\u6709\u8005\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u304C\u3042\u308A\u307E\u305B\u3093\u3002"},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_ko.java /st_wptg_1.9.0.0.0jdk/2 2016/04/12 02:39:51 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "document() \uD568\uC218 \uAD6C\uD604\uC774 com.sun.org.apache.xalan.internal.xslt.FuncDocument\uB85C \uB300\uCCB4\uB418\uC5C8\uC2B5\uB2C8\uB2E4!"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "\uC791\uC5C5\uC774 \uCEE8\uD14D\uC2A4\uD2B8\uC5D0 \uC885\uC18D\uC801\uC77C \uB54C \uCEE8\uD14D\uC2A4\uD2B8\uB294 \uB110\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "\uCEE8\uD14D\uC2A4\uD2B8\uC5D0 \uC18C\uC720\uC790 \uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4!"},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_pt_BR.java /st_wptg_1.8.0.0.0jdk/2 2013/09/11 12:46:54 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "a implementa\u00E7\u00E3o da fun\u00E7\u00E3o document() foi substitu\u00EDda por com.sun.org.apache.xalan.internal.xslt.FuncDocument!"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "O contexto n\u00E3o pode ser nulo porque a opera\u00E7\u00E3o \u00E9 dependente de contexto."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "o contexto n\u00E3o tem um documento de propriet\u00E1rio!"},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_sv.java /st_wptg_1.9.0.0.0jdk/2 2016/04/14 01:57:20 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "Implementeringen av funktionen document() har inte ersatts av com.sun.org.apache.xalan.internal.xslt.FuncDocument!"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "Kontexten kan inte vara null n\u00E4r \u00E5tg\u00E4rden \u00E4r kontextberoende."},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "context har inget \u00E4gardokument!"},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_zh_CN.java /st_wptg_1.8.0.0.0jdk/3 2013/11/11 11:39:28 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "document() \u51FD\u6570\u5B9E\u73B0\u5DF2\u66FF\u6362\u4E3A com.sun.org.apache.xalan.internal.xslt.FuncDocument!"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "\u8BE5\u64CD\u4F5C\u4E0E\u4E0A\u4E0B\u6587\u76F8\u5173\u65F6, \u4E0A\u4E0B\u6587\u4E0D\u80FD\u4E3A\u7A7A\u503C\u3002"},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "\u4E0A\u4E0B\u6587\u6CA1\u6709\u6240\u6709\u8005\u6587\u6863!"},
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -17,9 +17,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: XPATHErrorResources_zh_TW.java /st_wptg_1.9.0.0.0jdk/2 2016/04/11 20:46:43 gmolloy Exp $
- */
 package com.sun.org.apache.xpath.internal.res;
 
 import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
   public static final String ER_CURRENT_TAKES_NO_ARGS =
          "ER_CURRENT_TAKES_NO_ARGS";
   public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+  public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
   public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
          "ER_CONTEXT_HAS_NO_OWNERDOC";
   public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
   { ER_DOCUMENT_REPLACED,
       "document() \u51FD\u6578\u5BE6\u884C\u5DF2\u7531 com.sun.org.apache.xalan.internal.xslt.FuncDocument \u53D6\u4EE3\u3002"},
 
+  { ER_CONTEXT_CAN_NOT_BE_NULL,
+      "\u5982\u679C\u4F5C\u696D\u8207\u76F8\u95DC\u8CC7\u8A0A\u74B0\u5883\u76F8\u4F9D\uFF0C\u5247\u76F8\u95DC\u8CC7\u8A0A\u74B0\u5883\u4E0D\u53EF\u4EE5\u662F\u7A7A\u503C\u3002"},
+
   { ER_CONTEXT_HAS_NO_OWNERDOC,
       "\u76F8\u95DC\u8CC7\u8A0A\u74B0\u5883\u4E0D\u5177\u6709\u64C1\u6709\u8005\u6587\u4EF6\uFF01"},
 
--- a/jaxp/test/Makefile	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxp/test/Makefile	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -23,237 +23,16 @@
 # questions.
 #
 
-#
-# Makefile to run various JAXP tests
-#
-
-.DEFAULT : all
-
-# Empty these to get rid of some default rules
-.SUFFIXES:
-.SUFFIXES: .java
-CO=
-GET=
-
-# Utilities used
-AWK       = awk
-CAT       = cat
-CD        = cd
-CHMOD     = chmod
-CP        = cp
-CUT       = cut
-DIRNAME   = dirname
-ECHO      = echo
-EGREP     = egrep
-EXPAND    = expand
-FIND      = find
-MKDIR     = mkdir
-PWD       = pwd
-SED       = sed
-SORT      = sort
-TEE       = tee
-UNAME     = uname
-UNIQ      = uniq
-WC        = wc
-ZIPEXE    = zip
-
-# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
-UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
-
-# Commands to run on paths to make mixed paths for java on windows
-ifeq ($(UNAME_S), CYGWIN)
-  # Location of developer shared files
-  SLASH_JAVA = J:
-  GETMIXEDPATH = cygpath -m
-else
-  # Location of developer shared files
-  SLASH_JAVA = /java
-
-  GETMIXEDPATH=$(ECHO)
-endif
-
-# Root of this test area (important to use full paths in some places)
-TEST_ROOT := $(shell $(PWD))
-
-# Root of all test results
-ifdef TEST_OUTPUT_DIR
-  $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg)
-  ABS_TEST_OUTPUT_DIR := \
-    $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD))
-else
-  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)
-endif
-
-# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
-ifndef PRODUCT_HOME
-  # Try to use j2sdk-image if it exists
-  ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/j2sdk-image
-  PRODUCT_HOME :=                       		\
-    $(shell                             		\
-      if [ -d $(ABS_JDK_IMAGE) ] ; then 		\
-         $(ECHO) "$(ABS_JDK_IMAGE)";    		\
-       else                             		\
-         $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)";		\
-       fi)
-  PRODUCT_HOME := $(PRODUCT_HOME)
-endif
+default: all
 
-# Expect JPRT to set JPRT_PRODUCT_ARGS (e.g. -server etc.)
-#   Should be passed into 'java' only.
-#   Could include: -d64 -server -client OR any java option
-ifdef JPRT_PRODUCT_ARGS
-  JAVA_ARGS = $(JPRT_PRODUCT_ARGS)
-endif
-
-# Expect JPRT to set JPRT_PRODUCT_VM_ARGS (e.g. -Xcomp etc.)
-#   Should be passed into anything running the vm (java, javac, javadoc, ...).
-ifdef JPRT_PRODUCT_VM_ARGS
-  JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS)
-endif
-
-# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
-ifdef JPRT_ARCHIVE_BUNDLE
-  ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
-else
-  ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
-endif
-
-# How to create the test bundle (pass or fail, we want to create this)
-#   Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
-ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`     \
-	           && $(CD) $(ABS_TEST_OUTPUT_DIR)             \
-	           && $(CHMOD) -R a+r . \
-	           && $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . )
-
-# important results files
-SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
-STATS_TXT_NAME = Stats.txt
-STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)")
-RUNLIST   = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt")
-PASSLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt")
-FAILLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt")
-EXITCODE  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt")
+USE_JTREG_VERSION := 4.1
 
-TESTEXIT = \
-  if [ ! -s $(EXITCODE) ] ; then \
-    $(ECHO) "ERROR: EXITCODE file not filled in."; \
-    $(ECHO) "1" > $(EXITCODE); \
-  fi ; \
-  testExitCode=`$(CAT) $(EXITCODE)`; \
-  $(ECHO) "EXIT CODE: $${testExitCode}"; \
-  exit $${testExitCode}
-
-BUNDLE_UP_AND_EXIT = \
-( \
-  jtregExitCode=$$? && \
-  _summary="$(SUMMARY_TXT)"; \
-  $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
-  $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
-  if [ -r "$${_summary}" ] ; then \
-    $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
-    $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
-    $(EGREP) ' Passed\.' $(RUNLIST) \
-      | $(EGREP) -v ' Error\.' \
-      | $(EGREP) -v ' Failed\.' > $(PASSLIST); \
-    ( $(EGREP) ' Failed\.' $(RUNLIST); \
-      $(EGREP) ' Error\.' $(RUNLIST); \
-      $(EGREP) -v ' Passed\.' $(RUNLIST) ) \
-      | $(SORT) | $(UNIQ) > $(FAILLIST); \
-    if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \
-      $(EXPAND) $(FAILLIST) \
-        | $(CUT) -d' ' -f1 \
-        | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \
-      if [ $${jtregExitCode} = 0 ] ; then \
-        jtregExitCode=1; \
-      fi; \
-    fi; \
-    runc="`$(CAT) $(RUNLIST)      | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    passc="`$(CAT) $(PASSLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    failc="`$(CAT) $(FAILLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    exclc="FIXME CODETOOLS-7900176"; \
-    $(ECHO) "TEST STATS: name=$(UNIQUE_DIR)  run=$${runc}  pass=$${passc}  fail=$${failc}" \
-      >> $(STATS_TXT); \
-  else \
-    $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
-  fi; \
-  if [ -f $(STATS_TXT) ] ; then \
-    $(CAT) $(STATS_TXT); \
-  fi; \
-  $(ZIP_UP_RESULTS) ; \
-  $(TESTEXIT) \
-)
-
-################################################################
+include ../../test/TestCommon.gmk
 
 # Default make rule (runs default JAXP tests)
 all: jaxp_all
 	@$(ECHO) "Testing completed successfully"
 
-# Prep for output
-# Change execute permissions on shared library files.
-# Files in repositories should never have execute permissions, but
-# there are some tests that have pre-built shared libraries, and these
-# windows dll files must have execute permission. Adding execute
-# permission may happen automatically on windows when using certain
-# versions of mercurial but it cannot be guaranteed. And blindly
-# adding execute permission might be seen as a mercurial 'change', so
-# we avoid adding execute permission to repository files. But testing
-# from a plain source tree needs the chmod a+rx. Applying the chmod to
-# all shared libraries not just dll files. And with CYGWIN and sshd
-# service, you may need CYGWIN=ntsec for this to work.
-prep:
-	@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
-	@$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`
-	@if [ ! -d $(TEST_ROOT)/../.hg ] ; then                          \
-	  $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \)  \
-	        -exec $(CHMOD) a+rx {} \; ;                             \
-        fi
-
-# Cleanup
-clean:
-	@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
-	@$(RM) $(ARCHIVE_BUNDLE)
-
-################################################################
-
-# jtreg tests
-
-# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
-ifndef JT_HOME
-  JT_HOME = $(SLASH_JAVA)/re/jtreg/4.1/promoted/latest/binaries/jtreg
-  ifdef JPRT_JTREG_HOME
-    JT_HOME = $(JPRT_JTREG_HOME)
-  endif
-endif
-
-# Problematic tests to be excluded
-PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt))
-
-# Create exclude list for this platform and arch
-ifdef NO_EXCLUDES
-  JTREG_EXCLUSIONS =
-else
-  JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%)
-endif
-
-# convert list of directories to dos paths
-define MixedDirs
-$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}"))
-endef
-
-define SummaryInfo
-$(ECHO) "########################################################"
-$(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME))
-$(ECHO) "########################################################"
-endef
-
 # ------------------------------------------------------------------
 
 jaxp_%:
@@ -261,72 +40,3 @@
 	for each in $@; do \
 	        $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \
 	done
-
-# ------------------------------------------------------------------
-
-ifdef CONCURRENCY
-  JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
-endif
-ifdef EXTRA_JTREG_OPTIONS
-  JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
-endif
-
-# Default JTREG to run
-JTREG = $(JT_HOME)/bin/jtreg
-# run in agentvm mode
-JTREG_BASIC_OPTIONS += -agentvm
-# Only run automatic tests
-JTREG_BASIC_OPTIONS += -a
-# Always turn on assertions
-JTREG_ASSERT_OPTION = -ea -esa
-JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION)
-# Report details on all failed or error tests, times too
-JTREG_BASIC_OPTIONS += -v:fail,error,time
-# Retain all files for failing tests
-JTREG_BASIC_OPTIONS += -retain:fail,error
-# Ignore tests are not run and completely silent about it
-JTREG_IGNORE_OPTION = -ignore:quiet
-JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
-# Multiple by 4 the timeout numbers
-JTREG_TIMEOUT_OPTION =  -timeoutFactor:4
-JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
-# Set the max memory for jtreg control vm
-JTREG_MEMORY_OPTION = -J-Xmx512m
-JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
-# Set other vm and test options
-JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
-# Set the GC options for test vms
-#JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
-#JTREG_TEST_OPTIONS += $(JTREG_GC_OPTION)
-# Set the max memory for jtreg target test vms
-JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m
-JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
-
-# Make sure jtreg exists
-$(JTREG): $(JT_HOME)
-
-# Run jtreg
-jtreg_tests: prep $(PRODUCT_HOME) $(JTREG)
-	(                                                                    \
-	  ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)");                   \
-            export JT_HOME;                                                  \
-            $(shell $(GETMIXEDPATH) "$(JTREG)")                              \
-              $(JTREG_BASIC_OPTIONS)                                         \
-              -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport")  \
-              -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork")    \
-              -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                \
-              $(JTREG_EXCLUSIONS)                                            \
-              $(JTREG_TEST_OPTIONS)                                          \
-              $(TEST_SELECTION)                                                    \
-	  ) ;                                                                \
-	  $(BUNDLE_UP_AND_EXIT)                                              \
-	) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT)
-
-PHONY_LIST += jtreg_tests
-
-################################################################
-
-# Phony targets (e.g. these are not filenames)
-.PHONY: all clean prep $(PHONY_LIST)
-
-################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/DefaultFactoryWrapperTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.xpath.XPathFactory;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @library src/DefaultFactoryWrapperTest
+ * @build xmlwrapperprovider/*
+ * @run testng/othervm --add-modules=xmlwrapperprovider DefaultFactoryWrapperTest
+ * @bug 8169948 8169778
+ * @summary test customized provider wraps the built-in system-default implementation of JAXP factories
+ */
+public class DefaultFactoryWrapperTest {
+    private static final Module XML_MODULE = Layer.boot().findModule("java.xml").get();
+
+    private static final String PROVIDER_PACKAGE = "xwp";
+
+    /*
+     * Return JAXP factory and corresponding factory function.
+     */
+    @DataProvider(name = "jaxpFactories")
+    public Object[][] jaxpFactories() throws Exception {
+        return new Object[][] {
+                { DocumentBuilderFactory.newInstance(), (Produce)factory -> ((DocumentBuilderFactory)factory).newDocumentBuilder() },
+                { SAXParserFactory.newInstance(), (Produce)factory -> ((SAXParserFactory)factory).newSAXParser() },
+                { SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI), (Produce)factory -> ((SchemaFactory)factory).newSchema() },
+                { TransformerFactory.newInstance(), (Produce)factory -> ((TransformerFactory)factory).newTransformer() },
+                { XMLEventFactory.newInstance(), (Produce)factory -> ((XMLEventFactory)factory).createStartDocument() },
+                { XMLInputFactory.newInstance(), (Produce)factory -> ((XMLInputFactory)factory).createXMLEventReader(new StringReader("")) },
+                { XMLOutputFactory.newInstance(), (Produce)factory -> ((XMLOutputFactory)factory).createXMLEventWriter(new StringWriter()) },
+                { XPathFactory.newInstance(), (Produce)factory -> ((XPathFactory)factory).newXPath() },
+                { DatatypeFactory.newInstance(), (Produce)factory -> ((DatatypeFactory)factory).newXMLGregorianCalendar() }
+        };
+    }
+
+    /*
+     * Verify the factory comes from customized provider, and produces a built-in type.
+     */
+    @Test(dataProvider = "jaxpFactories")
+    public void testFactory(Object factory, Produce<Object, Object> p) throws Exception {
+        assertEquals(factory.getClass().getPackageName(), PROVIDER_PACKAGE);
+        assertSame(p.produce(factory).getClass().getModule(), XML_MODULE);
+    }
+
+    @FunctionalInterface
+    public interface Produce<T, R> {
+        R produce(T t) throws Exception;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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.
+ */
+
+module xmlwrapperprovider {
+    requires java.xml;
+
+    provides javax.xml.parsers.DocumentBuilderFactory with xwp.DocumentBuilderFactoryWrapper;
+    provides javax.xml.parsers.SAXParserFactory with xwp.SAXParserFactoryWrapper;
+    provides javax.xml.stream.XMLInputFactory with xwp.XMLInputFactoryWrapper;
+    provides javax.xml.stream.XMLOutputFactory with xwp.XMLOutputFactoryWrapper;
+    provides javax.xml.transform.TransformerFactory with xwp.TransformerFactoryWrapper;
+    provides javax.xml.validation.SchemaFactory with xwp.SchemaFactoryWrapper;
+    provides javax.xml.xpath.XPathFactory with xwp.XPathFactoryWrapper;
+    provides javax.xml.datatype.DatatypeFactory with xwp.DatatypeFactoryWrapper;
+    provides javax.xml.stream.XMLEventFactory with xwp.XMLEventFactoryWrapper;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/DatatypeFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.GregorianCalendar;
+
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public class DatatypeFactoryWrapper extends DatatypeFactory {
+    private DatatypeFactory defaultImpl = DatatypeFactory.newDefaultInstance();
+
+    @Override
+    public Duration newDuration(String lexicalRepresentation) {
+        return defaultImpl.newDuration(lexicalRepresentation);
+    }
+
+    @Override
+    public Duration newDuration(long durationInMilliSeconds) {
+        return defaultImpl.newDuration(durationInMilliSeconds);
+    }
+
+    @Override
+    public Duration newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days,
+            BigInteger hours, BigInteger minutes, BigDecimal seconds) {
+        return defaultImpl.newDuration(isPositive, years, months, days, hours, minutes, seconds);
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar() {
+        return defaultImpl.newXMLGregorianCalendar();
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation) {
+        return defaultImpl.newXMLGregorianCalendar(lexicalRepresentation);
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal) {
+        return defaultImpl.newXMLGregorianCalendar(cal);
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year, int month, int day, int hour,
+            int minute, int second, BigDecimal fractionalSecond, int timezone) {
+        return defaultImpl.newXMLGregorianCalendar(year, month, day, hour, minute, second, fractionalSecond, timezone);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/DocumentBuilderFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class DocumentBuilderFactoryWrapper extends DocumentBuilderFactory {
+    private DocumentBuilderFactory defaultImpl = DocumentBuilderFactory.newDefaultInstance();
+
+    @Override
+    public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
+        return defaultImpl.newDocumentBuilder();
+    }
+
+    @Override
+    public void setAttribute(String name, Object value) throws IllegalArgumentException {
+        defaultImpl.setAttribute(name, value);
+    }
+
+    @Override
+    public Object getAttribute(String name) throws IllegalArgumentException {
+        return defaultImpl.getAttribute(name);
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws ParserConfigurationException {
+        defaultImpl.setFeature(name, value);
+    }
+
+    @Override
+    public boolean getFeature(String name) throws ParserConfigurationException {
+        return defaultImpl.getFeature(name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/SAXParserFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+public class SAXParserFactoryWrapper extends SAXParserFactory {
+    private SAXParserFactory defaultImpl = SAXParserFactory.newDefaultInstance();
+
+    @Override
+    public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
+        return defaultImpl.newSAXParser();
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws ParserConfigurationException,
+            SAXNotRecognizedException, SAXNotSupportedException {
+        defaultImpl.setFeature(name, value);
+    }
+
+    @Override
+    public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException,
+            SAXNotSupportedException {
+        return defaultImpl.getFeature(name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/SchemaFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import javax.xml.transform.Source;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+public class SchemaFactoryWrapper extends SchemaFactory {
+    private SchemaFactory defaultImpl = SchemaFactory.newDefaultInstance();
+
+    @Override
+    public boolean isSchemaLanguageSupported(String schemaLanguage) {
+        return defaultImpl.isSchemaLanguageSupported(schemaLanguage);
+    }
+
+    @Override
+    public void setErrorHandler(ErrorHandler errorHandler) {
+        defaultImpl.setErrorHandler(errorHandler);
+    }
+
+    @Override
+    public ErrorHandler getErrorHandler() {
+        return defaultImpl.getErrorHandler();
+    }
+
+    @Override
+    public void setResourceResolver(LSResourceResolver resourceResolver) {
+        defaultImpl.setResourceResolver(resourceResolver);
+    }
+
+    @Override
+    public LSResourceResolver getResourceResolver() {
+        return defaultImpl.getResourceResolver();
+    }
+
+    @Override
+    public Schema newSchema(Source[] schemas) throws SAXException {
+        return defaultImpl.newSchema(schemas);
+    }
+
+    @Override
+    public Schema newSchema() throws SAXException {
+        return defaultImpl.newSchema();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/TransformerFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 xwp;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+
+public class TransformerFactoryWrapper extends TransformerFactory {
+    private TransformerFactory defaultImpl = TransformerFactory.newDefaultInstance();
+
+    @Override
+    public Transformer newTransformer(Source source) throws TransformerConfigurationException {
+        return defaultImpl.newTransformer(source);
+    }
+
+    @Override
+    public Transformer newTransformer() throws TransformerConfigurationException {
+        return defaultImpl.newTransformer();
+    }
+
+    @Override
+    public Templates newTemplates(Source source) throws TransformerConfigurationException {
+        return defaultImpl.newTemplates(source);
+    }
+
+    @Override
+    public Source getAssociatedStylesheet(Source source, String media, String title, String charset)
+            throws TransformerConfigurationException {
+        return defaultImpl.getAssociatedStylesheet(source, media, title, charset);
+    }
+
+    @Override
+    public void setURIResolver(URIResolver resolver) {
+        defaultImpl.setURIResolver(resolver);
+    }
+
+    @Override
+    public URIResolver getURIResolver() {
+        return defaultImpl.getURIResolver();
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws TransformerConfigurationException {
+        defaultImpl.setFeature(name, value);
+    }
+
+    @Override
+    public boolean getFeature(String name) {
+        return defaultImpl.getFeature(name);
+    }
+
+    @Override
+    public void setAttribute(String name, Object value) {
+        defaultImpl.setAttribute(name, value);
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        return defaultImpl.getAttribute(name);
+    }
+
+    @Override
+    public void setErrorListener(ErrorListener listener) {
+        defaultImpl.setErrorListener(listener);
+    }
+
+    @Override
+    public ErrorListener getErrorListener() {
+        return defaultImpl.getErrorListener();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/XMLEventFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import java.util.Iterator;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.Comment;
+import javax.xml.stream.events.DTD;
+import javax.xml.stream.events.EndDocument;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.EntityDeclaration;
+import javax.xml.stream.events.EntityReference;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+
+public class XMLEventFactoryWrapper extends XMLEventFactory {
+    private XMLEventFactory defaultImpl = XMLEventFactory.newDefaultFactory();
+
+    @Override
+    public void setLocation(Location location) {
+        defaultImpl.setLocation(location);
+    }
+
+    @Override
+    public Attribute createAttribute(String prefix, String namespaceURI, String localName, String value) {
+        return defaultImpl.createAttribute(prefix, namespaceURI, localName, value);
+    }
+
+    @Override
+    public Attribute createAttribute(String localName, String value) {
+        return defaultImpl.createAttribute(localName, value);
+    }
+
+    @Override
+    public Attribute createAttribute(QName name, String value) {
+        return defaultImpl.createAttribute(name, value);
+    }
+
+    @Override
+    public Namespace createNamespace(String namespaceURI) {
+        return defaultImpl.createNamespace(namespaceURI);
+    }
+
+    @Override
+    public Namespace createNamespace(String prefix, String namespaceUri) {
+        return defaultImpl.createNamespace(prefix, namespaceUri);
+    }
+
+    @Override
+    public StartElement createStartElement(QName name, Iterator attributes, Iterator namespaces) {
+        return defaultImpl.createStartElement(name, attributes, namespaces);
+    }
+
+    @Override
+    public StartElement createStartElement(String prefix, String namespaceUri, String localName) {
+        return defaultImpl.createStartElement(prefix, namespaceUri, localName);
+    }
+
+    @Override
+    public StartElement createStartElement(String prefix, String namespaceUri, String localName,
+            Iterator attributes, Iterator namespaces) {
+        return defaultImpl.createStartElement(prefix, namespaceUri, localName, attributes, namespaces);
+    }
+
+    @Override
+    public StartElement createStartElement(String prefix, String namespaceUri, String localName,
+            Iterator attributes, Iterator namespaces, NamespaceContext context) {
+        return defaultImpl.createStartElement(prefix, namespaceUri, localName, attributes, namespaces, context);
+    }
+
+    @Override
+    public EndElement createEndElement(QName name, Iterator namespaces) {
+        return defaultImpl.createEndElement(name, namespaces);
+    }
+
+    @Override
+    public EndElement createEndElement(String prefix, String namespaceUri, String localName) {
+        return defaultImpl.createEndElement(prefix, namespaceUri, localName);
+    }
+
+    @Override
+    public EndElement createEndElement(String prefix, String namespaceUri, String localName,
+            Iterator namespaces) {
+        return defaultImpl.createEndElement(prefix, namespaceUri, localName, namespaces);
+    }
+
+    @Override
+    public Characters createCharacters(String content) {
+        return defaultImpl.createCharacters(content);
+    }
+
+    @Override
+    public Characters createCData(String content) {
+        return defaultImpl.createCData(content);
+    }
+
+    @Override
+    public Characters createSpace(String content) {
+        return defaultImpl.createSpace(content);
+    }
+
+    @Override
+    public Characters createIgnorableSpace(String content) {
+        return defaultImpl.createIgnorableSpace(content);
+    }
+
+    @Override
+    public StartDocument createStartDocument() {
+        return defaultImpl.createStartDocument();
+    }
+
+    @Override
+    public StartDocument createStartDocument(String encoding, String version, boolean standalone) {
+        return defaultImpl.createStartDocument(encoding, version, standalone);
+    }
+
+    @Override
+    public StartDocument createStartDocument(String encoding, String version) {
+        return defaultImpl.createStartDocument(encoding, version);
+    }
+
+    @Override
+    public StartDocument createStartDocument(String encoding) {
+        return defaultImpl.createStartDocument(encoding);
+    }
+
+    @Override
+    public EndDocument createEndDocument() {
+        return defaultImpl.createEndDocument();
+    }
+
+    @Override
+    public EntityReference createEntityReference(String name, EntityDeclaration declaration) {
+        return defaultImpl.createEntityReference(name, declaration);
+    }
+
+    @Override
+    public Comment createComment(String text) {
+        return defaultImpl.createComment(text);
+    }
+
+    @Override
+    public ProcessingInstruction createProcessingInstruction(String target, String data) {
+        return defaultImpl.createProcessingInstruction(target, data);
+    }
+
+    @Override
+    public DTD createDTD(String dtd) {
+        return defaultImpl.createDTD(dtd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/XMLInputFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.xml.stream.EventFilter;
+import javax.xml.stream.StreamFilter;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLReporter;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.util.XMLEventAllocator;
+import javax.xml.transform.Source;
+
+public class XMLInputFactoryWrapper extends XMLInputFactory {
+    private XMLInputFactory defaultImpl = XMLInputFactory.newDefaultFactory();
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
+        return defaultImpl.createXMLStreamReader(reader);
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException {
+        return defaultImpl.createXMLStreamReader(source);
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(InputStream stream) throws XMLStreamException {
+        return defaultImpl.createXMLStreamReader(stream);
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(InputStream stream, String encoding)
+            throws XMLStreamException {
+        return defaultImpl.createXMLStreamReader(stream, encoding);
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(String systemId, InputStream stream)
+            throws XMLStreamException {
+        return defaultImpl.createXMLStreamReader(systemId, stream);
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException {
+        return defaultImpl.createXMLStreamReader(systemId, reader);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(Reader reader) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(reader);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(String systemId, Reader reader) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(systemId, reader);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(XMLStreamReader reader) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(reader);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(Source source) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(source);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(InputStream stream) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(stream);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(InputStream stream, String encoding) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(stream, encoding);
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(String systemId, InputStream stream) throws XMLStreamException {
+        return defaultImpl.createXMLEventReader(systemId, stream);
+    }
+
+    @Override
+    public XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter)
+            throws XMLStreamException {
+        return defaultImpl.createFilteredReader(reader, filter);
+    }
+
+    @Override
+    public XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter)
+            throws XMLStreamException {
+        return defaultImpl.createFilteredReader(reader, filter);
+    }
+
+    @Override
+    public XMLResolver getXMLResolver() {
+        return defaultImpl.getXMLResolver();
+    }
+
+    @Override
+    public void setXMLResolver(XMLResolver resolver) {
+        defaultImpl.setXMLResolver(resolver);
+    }
+
+    @Override
+    public XMLReporter getXMLReporter() {
+        return defaultImpl.getXMLReporter();
+    }
+
+    @Override
+    public void setXMLReporter(XMLReporter reporter) {
+        defaultImpl.setXMLReporter(reporter);
+    }
+
+    @Override
+    public void setProperty(String name, Object value) throws IllegalArgumentException {
+        defaultImpl.setProperty(name, value);
+    }
+
+    @Override
+    public Object getProperty(String name) throws IllegalArgumentException {
+        return defaultImpl.getProperty(name);
+    }
+
+    @Override
+    public boolean isPropertySupported(String name) {
+        return defaultImpl.isPropertySupported(name);
+    }
+
+    @Override
+    public void setEventAllocator(XMLEventAllocator allocator) {
+        defaultImpl.setEventAllocator(allocator);
+    }
+
+    @Override
+    public XMLEventAllocator getEventAllocator() {
+        return defaultImpl.getEventAllocator();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/XMLOutputFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 xwp;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+
+public class XMLOutputFactoryWrapper extends XMLOutputFactory {
+    private XMLOutputFactory defaultImpl = XMLOutputFactory.newDefaultFactory();
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(Writer stream) throws XMLStreamException {
+        return defaultImpl.createXMLStreamWriter(stream);
+    }
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(OutputStream stream) throws XMLStreamException {
+        return defaultImpl.createXMLStreamWriter(stream);
+    }
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(OutputStream stream, String encoding)
+            throws XMLStreamException {
+        return defaultImpl.createXMLStreamWriter(stream, encoding);
+    }
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(Result result) throws XMLStreamException {
+        return defaultImpl.createXMLStreamWriter(result);
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(Result result) throws XMLStreamException {
+        return defaultImpl.createXMLEventWriter(result);
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(OutputStream stream) throws XMLStreamException {
+        return defaultImpl.createXMLEventWriter(stream);
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(OutputStream stream, String encoding)
+            throws XMLStreamException {
+        return defaultImpl.createXMLEventWriter(stream, encoding);
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(Writer stream) throws XMLStreamException {
+        return defaultImpl.createXMLEventWriter(stream);
+    }
+
+    @Override
+    public void setProperty(String name, Object value) throws IllegalArgumentException {
+        defaultImpl.setProperty(name, value);
+    }
+
+    @Override
+    public Object getProperty(String name) throws IllegalArgumentException {
+        return defaultImpl.getProperty(name);
+    }
+
+    @Override
+    public boolean isPropertySupported(String name) {
+        return defaultImpl.isPropertySupported(name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/DefaultFactoryWrapperTest/xmlwrapperprovider/xwp/XPathFactoryWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package xwp;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathVariableResolver;
+
+public class XPathFactoryWrapper extends XPathFactory {
+    private XPathFactory defaultImpl = XPathFactory.newDefaultInstance();
+
+    @Override
+    public boolean isObjectModelSupported(String objectModel) {
+        return defaultImpl.isObjectModelSupported(objectModel);
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws XPathFactoryConfigurationException {
+        defaultImpl.setFeature(name, value);
+    }
+
+    @Override
+    public boolean getFeature(String name) throws XPathFactoryConfigurationException {
+        return defaultImpl.getFeature(name);
+    }
+
+    @Override
+    public void setXPathVariableResolver(XPathVariableResolver resolver) {
+        defaultImpl.setXPathVariableResolver(resolver);
+    }
+
+    @Override
+    public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
+        defaultImpl.setXPathFunctionResolver(resolver);
+    }
+
+    @Override
+    public XPath newXPath() {
+        return defaultImpl.newXPath();
+    }
+
+}
--- a/jaxws/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/jaxws/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -393,3 +393,4 @@
 29277a4e73077269358859c43bd6658593fc0410 jdk-9+145
 1461e3e07876ea61bd0a07355a43912c9b04022a jdk-9+146
 be37411855de5b76035bef6f1b0d90d8607f2205 jdk-9+147
+c8c9c334743caf8155c9809b6b4ac315d3a66476 jdk-9+148
--- a/jdk/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -390,3 +390,4 @@
 99b7853cfbd8227c4441de4b6119c10742556840 jdk-9+145
 6e4ff59afb5d0adf21a72c4ff534326594a99e5d jdk-9+146
 c41140100bf1e5c10c7b8f3bde91c16eff7485f5 jdk-9+147
+9098b2b9d997d65af0026fc2f39cf75234e26bc5 jdk-9+148
--- a/jdk/make/data/tzdata/VERSION	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/data/tzdata/VERSION	Tue Dec 13 02:04:23 2016 +0100
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2016i
+tzdata2016j
--- a/jdk/make/data/tzdata/africa	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/data/tzdata/africa	Tue Dec 13 02:04:23 2016 +0100
@@ -142,7 +142,7 @@
 # Cameroon
 # See Africa/Lagos.
 
-# Cape Verde
+# Cape Verde / Cabo Verde
 #
 # Shanks gives 1907 for the transition to CVT.
 # Perhaps the 1911-05-26 Portuguese decree
--- a/jdk/make/data/tzdata/asia	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/data/tzdata/asia	Tue Dec 13 02:04:23 2016 +0100
@@ -1606,12 +1606,12 @@
 # was "blended" with the Central zone.  Therefore, Kazakhstan now has
 # two time zones, and difference between them is one hour.  The zone
 # closer to UTC is the former Western zone (probably still called the
-# same), encompassing four provinces in the west: Aqtobe, Atyrau,
-# Mangghystau, and West Kazakhstan.  The other zone encompasses
+# same), encompassing four provinces in the west: Aqtöbe, Atyraū,
+# Mangghystaū, and West Kazakhstan.  The other zone encompasses
 # everything else....  I guess that would make Kazakhstan time zones
 # de jure UTC+5 and UTC+6 respectively.
 
-# From Stepan Golosunov (2016-03-27) ([*] means see later comments below):
+# From Stepan Golosunov (2016-03-27):
 # Review of the linked documents from http://adilet.zan.kz/
 # produced the following data for post-1991 Kazakhstan:
 #
@@ -1657,7 +1657,7 @@
 #
 # This implies that on 1991-03-31 Asia/Oral remained on +04/+05 while
 # the rest of Kazakhstan switched from +06/+07 to +05/06 or from +05/06
-# to +04/+05. It's unclear how Kzyl-Orda oblast moved into the fifth
+# to +04/+05. It's unclear how Qyzylorda oblast moved into the fifth
 # time belt. (By switching from +04/+05 to +05/+06 on 1991-09-29?) ...
 #
 # 1. Act of the Cabinet of Ministers of the Republic of Kazakhstan
@@ -1670,25 +1670,25 @@
 # on the whole territory of Kazakhstan 1 hour forward on 1992-01-19 at
 # 2:00, specified DST rules.  It acknowledged that Kazakhstan was
 # located in the fourth and the fifth time belts and specified the
-# border between them to be located east of Kustanay and Aktyubinsk
-# oblasts (notably including Turgai and Kzyl-Orda oblasts into the fifth
+# border between them to be located east of Qostanay and Aktyubinsk
+# oblasts (notably including Turgai and Qyzylorda oblasts into the fifth
 # time belt).
 #
 # This means switch on 1992-01-19 at 2:00 from +04/+05 to +05/+06 for
-# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyrau and Kustanay oblasts; from
-# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk) [*]....
+# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyraū and Qostanay oblasts; from
+# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk)....
 #
 # 2. Act of the Cabinet of Ministers of the Republic of Kazakhstan
 # from 1992-03-27 No. 284
 # http://adilet.zan.kz/rus/docs/P920000284_
-# cancels extra hour ("decree time") for Uralsk and Kzyl-Orda oblasts
+# cancels extra hour ("decree time") for Uralsk and Qyzylorda oblasts
 # since the last Sunday of March 1992, while keeping them in the fourth
 # and the fifth time belts respectively.
 #
 # 3. Order of the Prime Minister of the Republic of Kazakhstan
 # from 1994-09-23 No. 384
 # http://adilet.zan.kz/rus/docs/R940000384_
-# cancels the extra hour ("decree time") on the territory of Mangystau
+# cancels the extra hour ("decree time") on the territory of Mangghystaū
 # oblast since the last Sunday of September 1994 (saying that time on
 # the territory would correspond to the third time belt as a
 # result)....
@@ -1702,14 +1702,11 @@
 # 5. Act of the Government of the Republic of Kazakhstan
 # from 1999-03-26 No. 305
 # http://adilet.zan.kz/rus/docs/P990000305_
-# cancels the extra hour ("decree time") for Atyrau oblast since the
+# cancels the extra hour ("decree time") for Atyraū oblast since the
 # last Sunday of March 1999 while retaining the oblast in the fourth
 # time belt.
 #
-# This means change from +05/+06 to +04/+05.
-#
-# There is no zone for Atyrau currently (listed under Asia/Aqtau in
-# zone1970.tab).[*]
+# This means change from +05/+06 to +04/+05....
 #
 # 6. Act of the Government of the Republic of Kazakhstan
 # from 2000-11-23 No. 1749
@@ -1719,10 +1716,10 @@
 # The only changes I noticed are in definition of the border between the
 # fourth and the fifth time belts.  They account for changes in spelling
 # and administrative division (splitting of Turgai oblast in 1997
-# probably changed time in territories incorporated into Kostanay oblast
-# (including Arkalyk) from +06/+07 to +05/+06) and move Kyzylorda oblast
+# probably changed time in territories incorporated into Qostanay oblast
+# (including Arkalyk) from +06/+07 to +05/+06) and move Qyzylorda oblast
 # from being in the fifth time belt and not using decree time into the
-# fourth time belt (no change in practice).[*]
+# fourth time belt (no change in practice).
 #
 # 7. Act of the Government of the Republic of Kazakhstan
 # from 2003-12-29 No. 1342
@@ -1732,7 +1729,7 @@
 # 8. Act of the Government of the Republic of Kazakhstan
 # from 2004-07-20 No. 775
 # http://adilet.zan.kz/rus/archive/docs/P040000775_/20.07.2004
-# modified the 2000-11-23 act to move Kostanay and Kyzylorda oblasts into
+# modified the 2000-11-23 act to move Qostanay and Qyzylorda oblasts into
 # the fifth time belt and add Aktobe oblast to the list of regions not
 # using extra hour ("decree time"), leaving Kazakhstan with only 2 time
 # zones (+04/+05 and +06/+07).  The changes were to be implemented
@@ -1744,14 +1741,14 @@
 # http://adilet.zan.kz/rus/docs/P040001059_
 # modified the 2000-11-23 act to remove exceptions from the "decree time"
 # (leaving Kazakhstan in +05/+06 and +06/+07 zones), amended the
-# 2004-07-20 act to implement changes for Atyrau, West Kazakhstan,
-# Kostanay, Kyzylorda and Mangystau oblasts by not moving clocks
-# during the 2014 transition to "winter" time.
+# 2004-07-20 act to implement changes for Atyraū, West Kazakhstan,
+# Qostanay, Qyzylorda and Mangghystaū oblasts by not moving clocks
+# during the 2004 transition to "winter" time.
 #
-# This means transition from +04/+05 to +05/+06 for Atyrau oblast (no
+# This means transition from +04/+05 to +05/+06 for Atyraū oblast (no
 # zone currently), Asia/Oral, Asia/Aqtau and transition from +05/+06 to
-# +06/+07 for Kostanay oblast (Kostanay and Arkalyk, no zones currently)
-# and Asia/Qyzylorda on 2004-10-31 at 3:00....[*]
+# +06/+07 for Qostanay oblast (Qostanay and Arkalyk, no zones currently)
+# and Asia/Qyzylorda on 2004-10-31 at 3:00....
 #
 # 10. Act of the Government of the Republic of Kazakhstan
 # from 2005-03-15 No. 231
@@ -1767,14 +1764,9 @@
 # Kazakh 1992-01-13 act appears to provide the same rules and 1992-03-27
 # act was to be enacted on the last Sunday of March 1992.
 
-# From Paul Eggert (2016-04-15):
-# The tables below should reflect Stepan Golosunov's remarks above,
-# except for the items marked "[*]" which I haven't gotten to yet.
-# It looks like we will need new zones Asia/Atyrau and Asia/Qostanay
-# to handle changes from 1992 through 2004 that we did not previously
-# know about.
+# From Paul Eggert (2016-11-07):
+# The tables below reflect Golosunov's remarks, with exceptions as noted.
 
-#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
@@ -1787,6 +1779,8 @@
 			6:00 RussiaAsia	+06/+07	2004 Oct 31  2:00s
 			6:00	-	+06
 # Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
+# This currently includes Qostanay (aka Kostanay, Kustanay) (KZ-KUS);
+# see comments below.
 Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
 			5:00	-	+05	1981 Apr  1
@@ -1798,7 +1792,21 @@
 			6:00 RussiaAsia	+06/+07	1992 Mar 29  2:00s
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
 			6:00	-	+06
-# Aqtobe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
+# The following zone is like Asia/Qyzylorda except for being one
+# hour earlier from 1991-09-29 to 1992-03-29.  The 1991/2 rules for
+# Qostenay are unclear partly because of the 1997 Turgai
+# reorganization, so this zone is commented out for now.
+#Zone	Asia/Qostanay	4:14:20 -	LMT	1924 May  2
+#			4:00	-	+04	1930 Jun 21
+#			5:00	-	+05	1981 Apr  1
+#			5:00	1:00	+06	1981 Oct  1
+#			6:00	-	+06	1982 Apr  1
+#			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
+#			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
+#			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
+#			6:00	-	+06
+#
+# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
 Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
 			5:00	-	+05	1981 Apr  1
@@ -1808,14 +1816,11 @@
 			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
 			5:00	-	+05
-# Qostanay (KZ-KUS)
-
-# Mangghystau (KZ-MAN)
+# Mangghystaū (KZ-MAN)
 # Aqtau was not founded until 1963, but it represents an inhabited region,
 # so include time stamps before 1963.
 Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
-			5:00	-	+05	1963
 			5:00	-	+05	1981 Oct  1
 			6:00	-	+06	1982 Apr  1
 			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
@@ -1823,7 +1828,17 @@
 			5:00 RussiaAsia	+05/+06	1994 Sep 25  2:00s
 			4:00 RussiaAsia	+04/+05	2004 Oct 31  2:00s
 			5:00	-	+05
-
+# Atyraū (KZ-ATY) is like Mangghystaū except it switched from
+# +04/+05 to +05/+06 in spring 1999, not fall 1994.
+Zone	Asia/Atyrau	3:27:44	-	LMT	1924 May  2
+			4:00	-	+04	1930 Jun 21
+			5:00	-	+05	1981 Oct  1
+			6:00	-	+06	1982 Apr  1
+			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
+			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
+			5:00 RussiaAsia	+05/+06	1999 Mar 28  2:00s
+			4:00 RussiaAsia	+04/+05	2004 Oct 31  2:00s
+			5:00	-	+05
 # West Kazakhstan (KZ-ZAP)
 # From Paul Eggert (2016-03-18):
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
@@ -2639,7 +2654,7 @@
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
-			2:00	Zion	EET	1948 May 15
+			2:00	Zion	EET/EEST 1948 May 15
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
@@ -2652,7 +2667,7 @@
 			2:00 Palestine	EE%sT
 
 Zone	Asia/Hebron	2:20:23	-	LMT	1900 Oct
-			2:00	Zion	EET	1948 May 15
+			2:00	Zion	EET/EEST 1948 May 15
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
--- a/jdk/make/data/tzdata/europe	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/data/tzdata/europe	Tue Dec 13 02:04:23 2016 +0100
@@ -924,7 +924,7 @@
 # Cyprus
 # Please see the 'asia' file for Asia/Nicosia.
 
-# Czech Republic
+# Czech Republic / Czechia
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
 Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
@@ -2624,10 +2624,9 @@
 			 3:00	-	+03	2016 Mar 27  2:00s
 			 4:00	-	+04
 
-# From Paul Eggert (2016-03-18):
+# From Paul Eggert (2016-11-11):
 # Europe/Volgograd covers:
 # 34	RU-VGG	Volgograd Oblast
-# 64	RU-SAR	Saratov Oblast
 # The 1988 transition is from USSR act No. 5 (1988-01-04).
 
 Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
@@ -2640,6 +2639,27 @@
 			 4:00	-	+04	2014 Oct 26  2:00s
 			 3:00	-	+03
 
+# From Paul Eggert (2016-11-11):
+# Europe/Saratov covers:
+# 64	RU-SAR	Saratov Oblast
+
+# From Yuri Konotopov (2016-11-11):
+# Dec 4, 2016 02:00 UTC+3....  Saratov Region's local time will be ... UTC+4.
+# From Stepan Golosunov (2016-11-11):
+# ... Byalokoz listed Saratov on 03:04:18.
+# From Stepan Golosunov (2016-11-22):
+# http://publication.pravo.gov.ru/Document/View/0001201611220031
+
+Zone Europe/Saratov	 3:04:18 -	LMT	1919 Jul  1  0:00u
+			 3:00	-	+03	1930 Jun 21
+			 4:00	Russia	+04/+05	1988 Mar 27  2:00s
+			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
+			 4:00	-	+04	1992 Mar 29  2:00s
+			 3:00	Russia	+03/+04	2011 Mar 27  2:00s
+			 4:00	-	+04	2014 Oct 26  2:00s
+			 3:00	-	+03	2016 Dec  4  2:00s
+			 4:00	-	+04
+
 # From Paul Eggert (2016-03-18):
 # Europe/Kirov covers:
 # 43	RU-KIR	Kirov Oblast
--- a/jdk/make/data/tzdata/iso3166.tab	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/data/tzdata/iso3166.tab	Tue Dec 13 02:04:23 2016 +0100
@@ -98,7 +98,7 @@
 CR	Costa Rica
 CU	Cuba
 CV	Cape Verde
-CW	Curacao
+CW	Curaçao
 CX	Christmas Island
 CY	Cyprus
 CZ	Czech Republic
--- a/jdk/make/data/tzdata/zone.tab	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/data/tzdata/zone.tab	Tue Dec 13 02:04:23 2016 +0100
@@ -262,7 +262,8 @@
 KZ	+4315+07657	Asia/Almaty	Kazakhstan (most areas)
 KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda/Kyzylorda/Kzyl-Orda
 KZ	+5017+05710	Asia/Aqtobe	Aqtobe/Aktobe
-KZ	+4431+05016	Asia/Aqtau	Atyrau/Atirau/Gur'yev, Mangghystau/Mankistau
+KZ	+4431+05016	Asia/Aqtau	Mangghystau/Mankistau
+KZ	+4707+05156	Asia/Atyrau	Atyrau/Atirau/Gur'yev
 KZ	+5113+05121	Asia/Oral	West Kazakhstan
 LA	+1758+10236	Asia/Vientiane
 LB	+3353+03530	Asia/Beirut
@@ -353,14 +354,15 @@
 RU	+5443+02030	Europe/Kaliningrad	MSK-01 - Kaliningrad
 RU	+554521+0373704	Europe/Moscow	MSK+00 - Moscow area
 RU	+4457+03406	Europe/Simferopol	MSK+00 - Crimea
-RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd, Saratov
+RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd
 RU	+5836+04939	Europe/Kirov	MSK+00 - Kirov
 RU	+4621+04803	Europe/Astrakhan	MSK+01 - Astrakhan
+RU	+5134+04602	Europe/Saratov	MSK+01 - Saratov
+RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
 RU	+5312+05009	Europe/Samara	MSK+01 - Samara, Udmurtia
-RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
 RU	+5651+06036	Asia/Yekaterinburg	MSK+02 - Urals
 RU	+5500+07324	Asia/Omsk	MSK+03 - Omsk
-RU	+5502+08255	Asia/Novosibirsk	MSK+03 - Novosibirsk
+RU	+5502+08255	Asia/Novosibirsk	MSK+04 - Novosibirsk
 RU	+5322+08345	Asia/Barnaul	MSK+04 - Altai
 RU	+5630+08458	Asia/Tomsk	MSK+04 - Tomsk
 RU	+5345+08707	Asia/Novokuznetsk	MSK+04 - Kemerovo
--- a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -38,7 +38,6 @@
       OPTIMIZATION := LOW, \
       CFLAGS := $(CFLAGS_JDKLIB) \
           $(addprefix -I, $(LIBJ2UCRYPTO_SRC)), \
-      DISABLED_WARNINGS_solstudio := E_MACRO_REDEFINED, \
       MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2ucrypto/mapfile-vers, \
       LDFLAGS := $(LDFLAGS_JDKLIB), \
       LIBS := $(LIBDL), \
--- a/jdk/make/mapfiles/libnio/mapfile-linux	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-linux	Tue Dec 13 02:04:23 2016 +0100
@@ -60,6 +60,7 @@
                 Java_sun_nio_ch_FileChannelImpl_position0;
                 Java_sun_nio_ch_FileChannelImpl_transferTo0;
                 Java_sun_nio_ch_FileChannelImpl_unmap0;
+		Java_sun_nio_ch_FileDispatcherImpl_allocate0;
                 Java_sun_nio_ch_FileDispatcherImpl_close0;
                 Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
 		Java_sun_nio_ch_FileDispatcherImpl_force0;
--- a/jdk/make/mapfiles/libnio/mapfile-macosx	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-macosx	Tue Dec 13 02:04:23 2016 +0100
@@ -43,6 +43,7 @@
                 Java_sun_nio_ch_FileChannelImpl_position0;
                 Java_sun_nio_ch_FileChannelImpl_transferTo0;
                 Java_sun_nio_ch_FileChannelImpl_unmap0;
+		Java_sun_nio_ch_FileDispatcherImpl_allocate0;
                 Java_sun_nio_ch_FileDispatcherImpl_close0;
                 Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
 		Java_sun_nio_ch_FileDispatcherImpl_force0;
--- a/jdk/make/mapfiles/libnio/mapfile-solaris	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-solaris	Tue Dec 13 02:04:23 2016 +0100
@@ -48,6 +48,7 @@
                 Java_sun_nio_ch_FileChannelImpl_position0;
                 Java_sun_nio_ch_FileChannelImpl_transferTo0;
                 Java_sun_nio_ch_FileChannelImpl_unmap0;
+		Java_sun_nio_ch_FileDispatcherImpl_allocate0;
                 Java_sun_nio_ch_FileDispatcherImpl_close0;
                 Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
 		Java_sun_nio_ch_FileDispatcherImpl_force0;
--- a/jdk/src/java.base/macosx/classes/apple/security/KeychainStore.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/macosx/classes/apple/security/KeychainStore.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -911,7 +911,6 @@
         return true;
     }
 
-    @SuppressWarnings("deprecation")
     private byte[] fetchPrivateKeyFromBag(byte[] privateKeyInfo) throws IOException, NoSuchAlgorithmException, CertificateException
     {
         byte[] returnValue = null;
@@ -972,7 +971,6 @@
         return returnValue;
     }
 
-    @SuppressWarnings("deprecation")
     private byte[] extractKeyData(DerInputStream stream)
         throws IOException, NoSuchAlgorithmException, CertificateException
     {
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,10 +68,10 @@
         }
 
         byte paddingOctet = (byte) (len & 0xff);
-        byte[] padding = new byte[len];
+        byte[] padding = new byte[len - 1];
         SunJCE.getRandom().nextBytes(padding);
-        padding[len-1] = paddingOctet;
-        System.arraycopy(padding, 0, in, off, len);
+        System.arraycopy(padding, 0, in, off, len - 1);
+        in[off + len - 1] = paddingOctet;
         return;
     }
 
@@ -101,7 +101,7 @@
             return -1;
         }
 
-        int start = off + len - ((int)lastByte & 0x0ff);
+        int start = off + len - padValue;
         if (start < off) {
             return -1;
         }
--- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -63,10 +63,10 @@
                 "\u5727\u7E2E\u30AA\u30D7\u30B7\u30E7\u30F3",
                 "  -r\u3001--repack                    jar\u3092\u518D\u5727\u7E2E\u307E\u305F\u306F\u6B63\u898F\u5316\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3001",
                 "                                  jarsigner\u306B\u3088\u308B\u7F72\u540D\u306B\u9069\u3057\u307E\u3059",
-                "  -g\u3001--no-gzip                   \u30D7\u30EC\u30FC\u30F3\u306A\u5727\u7E2E\u30D5\u30A1\u30A4\u30EB\u3092\u51FA\u529B\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3001",
+                "  -g\u3001--no-gzip                   \u30D7\u30EC\u30FC\u30F3\u306Apack\u30D5\u30A1\u30A4\u30EB\u3092\u51FA\u529B\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3001",
                 "                                  \u30D5\u30A1\u30A4\u30EB\u5727\u7E2E\u30E6\u30FC\u30C6\u30A3\u30EA\u30C6\u30A3\u306B\u3088\u308B\u5727\u7E2E\u306B\u9069\u3057\u307E\u3059",
-                "  --gzip                          (\u30C7\u30D5\u30A9\u30EB\u30C8)\u5727\u7E2E\u51FA\u529B\u3092gzip\u3067",
-                "                                  \u5727\u7E2E\u306E\u5F8C\u51E6\u7406\u3092\u884C\u3044\u307E\u3059",
+                "  --gzip                          (\u30C7\u30D5\u30A9\u30EB\u30C8) pack\u51FA\u529B\u3092\u5F8C\u51E6\u7406\u3067\u5727\u7E2E\u3057\u307E\u3059",
+                "                                  (gzip\u3092\u4F7F\u7528)",
                 "  -G\u3001--strip-debug               \u5727\u7E2E\u4E2D\u306B\u30C7\u30D0\u30C3\u30B0\u5C5E\u6027(SourceFile\u3001",
                 "                                  LineNumberTable\u3001LocalVariableTable",
                 "                                  \u3001LocalVariableTypeTable)\u3092\u524A\u9664\u3057\u307E\u3059",
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -350,16 +350,24 @@
          * The first pattern that matches, working from left to right, determines
          * the {@link Status#ALLOWED Status.ALLOWED}
          * or {@link Status#REJECTED Status.REJECTED} result.
-         * If nothing matches, the result is {@link Status#UNDECIDED Status.UNDECIDED}.
+         * If the limits are not exceeded and no pattern matches the class,
+         * the result is {@link Status#UNDECIDED Status.UNDECIDED}.
          *
          * @param pattern the pattern string to parse; not null
-         * @return a filter to check a class being deserialized; may be null;
+         * @return a filter to check a class being deserialized;
          *          {@code null} if no patterns
-         * @throws IllegalArgumentException
-         *                if a limit is missing the name, or the long value
-         *                is not a number or is negative,
-         *                or the module name is missing if the pattern contains "/"
-         *                or if the package is missing for ".*" and ".**"
+         * @throws IllegalArgumentException if the pattern string is illegal or
+         *         malformed and cannot be parsed.
+         *         In particular, if any of the following is true:
+         * <ul>
+         * <li>   if a limit is missing the name or the name is not one of
+         *        "maxdepth", "maxrefs", "maxbytes", or "maxarray"
+         * <li>   if the value of the limit can not be parsed by
+         *        {@link Long#parseLong Long.parseLong} or is negative
+         * <li>   if the pattern contains "/" and the module name is missing
+         *        or the remaining pattern is empty
+         * <li>   if the package is missing for ".*" and ".**"
+         * </ul>
          */
         public static ObjectInputFilter createFilter(String pattern) {
             Objects.requireNonNull(pattern, "pattern");
@@ -402,14 +410,19 @@
              * Returns an ObjectInputFilter from a string of patterns.
              *
              * @param pattern the pattern string to parse
-             * @return a filter to check a class being deserialized; not null
+             * @return a filter to check a class being deserialized;
+             *          {@code null} if no patterns
              * @throws IllegalArgumentException if the parameter is malformed
              *                if the pattern is missing the name, the long value
              *                is not a number or is negative.
              */
             static ObjectInputFilter createFilter(String pattern) {
-                Global filter = new Global(pattern);
-                return filter.isEmpty() ? null : filter;
+                try {
+                    return new Global(pattern);
+                } catch (UnsupportedOperationException uoe) {
+                    // no non-empty patterns
+                    return null;
+                }
             }
 
             /**
@@ -417,8 +430,10 @@
              *
              * @param pattern a pattern string of filters
              * @throws IllegalArgumentException if the pattern is malformed
+             * @throws UnsupportedOperationException if there are no non-empty patterns
              */
             private Global(String pattern) {
+                boolean hasLimits = false;
                 this.pattern = pattern;
 
                 maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
@@ -436,6 +451,7 @@
                     }
                     if (parseLimit(p)) {
                         // If the pattern contained a limit setting, i.e. type=value
+                        hasLimits = true;
                         continue;
                     }
                     boolean negate = p.charAt(0) == '!';
@@ -510,18 +526,9 @@
                         filters.add(c -> moduleName.equals(c.getModule().getName()) ? patternFilter.apply(c) : Status.UNDECIDED);
                     }
                 }
-            }
-
-            /**
-             * Returns if this filter has any checks.
-             * @return {@code true} if the filter has any checks, {@code false} otherwise
-             */
-            private boolean isEmpty() {
-                return filters.isEmpty() &&
-                        maxArrayLength == Long.MAX_VALUE &&
-                        maxDepth == Long.MAX_VALUE &&
-                        maxReferences == Long.MAX_VALUE &&
-                        maxStreamBytes == Long.MAX_VALUE;
+                if (filters.isEmpty() && !hasLimits) {
+                    throw new UnsupportedOperationException("no non-empty patterns");
+                }
             }
 
             /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Tue Dec 13 02:04:23 2016 +0100
@@ -657,13 +657,11 @@
      * <pre>
      *     Class.forName(desc.getName(), false, loader)
      * </pre>
-     * where <code>loader</code> is determined as follows: if there is a
-     * method on the current thread's stack whose declaring class is not a
-     * <a href="../lang/ClassLoader.html#builtinLoaders">
-     * <em>platform class</em></a>, then <code>loader</code> is
-     * the class loader of such class; otherwise, <code>loader</code>
-     * is the {@linkplain ClassLoader#getPlatformClassLoader()
-     * platform class loader}.  If this call results in a
+     * where <code>loader</code> is the first class loader on the current
+     * thread's stack (starting from the currently executing method) that is
+     * neither the {@linkplain ClassLoader#getPlatformClassLoader() platform
+     * class loader} nor its ancestor; otherwise, <code>loader</code> is the
+     * <em>platform class loader</em>. If this call results in a
      * <code>ClassNotFoundException</code> and the name of the passed
      * <code>ObjectStreamClass</code> instance is the Java language keyword
      * for a primitive type or void, then the <code>Class</code> object
@@ -721,13 +719,11 @@
      * <pre>
      *     Class.forName(i, false, loader)
      * </pre>
-     * where <code>loader</code> is determined as follows: if there is a
-     * method on the current thread's stack whose declaring class is not a
-     * <a href="../lang/ClassLoader.html#builtinLoaders">
-     * <em>platform class</em></a>, then <code>loader</code> is
-     * the class loader of such class; otherwise, <code>loader</code>
-     * is the {@linkplain ClassLoader#getPlatformClassLoader()
-     * platform class loader}.
+     * where <code>loader</code> is the first class loader on the current
+     * thread's stack (starting from the currently executing method) that is
+     * neither the {@linkplain ClassLoader#getPlatformClassLoader() platform
+     * class loader} nor its ancestor; otherwise, <code>loader</code> is the
+     * <em>platform class loader</em>.
      * Unless any of the resolved interfaces are non-public, this same value
      * of <code>loader</code> is also the class loader passed to
      * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
@@ -1168,6 +1164,13 @@
      * for each class and reference in the stream.
      * The filter can check any or all of the class, the array length, the number
      * of references, the depth of the graph, and the size of the input stream.
+     * The depth is the number of nested {@linkplain #readObject readObject}
+     * calls starting with the reading of the root of the graph being deserialized
+     * and the current object being deserialized.
+     * The number of references is the cumulative number of objects and references
+     * to objects already read from the stream including the current object being read.
+     * The filter is invoked only when reading objects from the stream and for
+     * not primitives.
      * <p>
      * If the filter returns {@link ObjectInputFilter.Status#REJECTED Status.REJECTED},
      * {@code null} or throws a {@link RuntimeException},
@@ -1182,8 +1185,9 @@
      *
      * @implSpec
      * The filter, when not {@code null}, is invoked during {@link #readObject readObject}
-     * and {@link #readUnshared readUnshared} for each object
-     * (regular or class) in the stream including the following:
+     * and {@link #readUnshared readUnshared} for each object (regular or class) in the stream.
+     * Strings are treated as primitives and do not invoke the filter.
+     * The filter is called for:
      * <ul>
      *     <li>each object reference previously deserialized from the stream
      *     (class is {@code null}, arrayLength is -1),
@@ -2370,16 +2374,10 @@
                                               int ndoubles);
 
     /**
-     * Returns the first non-null and non-platform class loader
-     * (not counting class loaders of generated reflection implementation classes)
-     * up the execution stack, or null if only code from the bootstrap and
-     * platform class loader is on the stack.
-     * This method is also called via reflection by the following RMI-IIOP class:
-     *
-     *     com.sun.corba.se.internal.util.JDKClassLoader
-     *
-     * This method should not be removed or its signature changed without
-     * corresponding modifications to the above class.
+     * Returns the first non-null and non-platform class loader (not counting
+     * class loaders of generated reflection implementation classes) up the
+     * execution stack, or the platform class loader if only code from the
+     * bootstrap and platform class loader is on the stack.
      */
     private static ClassLoader latestUserDefinedLoader() {
         return jdk.internal.misc.VM.latestUserDefinedLoader();
--- a/jdk/src/java.base/share/classes/java/lang/Class.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1277,33 +1277,40 @@
     }
 
     private static final class EnclosingMethodInfo {
-        private Class<?> enclosingClass;
-        private String name;
-        private String descriptor;
-
-        private EnclosingMethodInfo(Object[] enclosingInfo) {
+        private final Class<?> enclosingClass;
+        private final String name;
+        private final String descriptor;
+
+        static void validate(Object[] enclosingInfo) {
             if (enclosingInfo.length != 3)
                 throw new InternalError("Malformed enclosing method information");
             try {
                 // The array is expected to have three elements:
 
                 // the immediately enclosing class
-                enclosingClass = (Class<?>) enclosingInfo[0];
+                Class<?> enclosingClass = (Class<?>)enclosingInfo[0];
                 assert(enclosingClass != null);
 
                 // the immediately enclosing method or constructor's
                 // name (can be null).
-                name            = (String)   enclosingInfo[1];
+                String name = (String)enclosingInfo[1];
 
                 // the immediately enclosing method or constructor's
                 // descriptor (null iff name is).
-                descriptor      = (String)   enclosingInfo[2];
+                String descriptor = (String)enclosingInfo[2];
                 assert((name != null && descriptor != null) || name == descriptor);
             } catch (ClassCastException cce) {
                 throw new InternalError("Invalid type in enclosing method information", cce);
             }
         }
 
+        EnclosingMethodInfo(Object[] enclosingInfo) {
+            validate(enclosingInfo);
+            this.enclosingClass = (Class<?>)enclosingInfo[0];
+            this.name = (String)enclosingInfo[1];
+            this.descriptor = (String)enclosingInfo[2];
+        }
+
         boolean isPartial() {
             return enclosingClass == null || name == null || descriptor == null;
         }
@@ -1481,7 +1488,7 @@
 
         if (enclosingInfo == null) {
             // This is a top level or a nested class or an inner class (a, b, or c)
-            enclosingCandidate = getDeclaringClass();
+            enclosingCandidate = getDeclaringClass0();
         } else {
             Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
             // This is a local class or an anonymous class (d or e)
@@ -1548,14 +1555,6 @@
     }
 
     /**
-     * Character.isDigit answers {@code true} to some non-ascii
-     * digits.  This one does not.
-     */
-    private static boolean isAsciiDigit(char c) {
-        return '0' <= c && c <= '9';
-    }
-
-    /**
      * Returns the canonical name of the underlying class as
      * defined by the Java Language Specification.  Returns null if
      * the underlying class does not have a canonical name (i.e., if
@@ -1594,7 +1593,8 @@
      * @since 1.5
      */
     public boolean isAnonymousClass() {
-        return "".equals(getSimpleName());
+        return !isArray() && isLocalOrAnonymousClass() &&
+                getSimpleBinaryName0() == null;
     }
 
     /**
@@ -1605,7 +1605,8 @@
      * @since 1.5
      */
     public boolean isLocalClass() {
-        return isLocalOrAnonymousClass() && !isAnonymousClass();
+        return isLocalOrAnonymousClass() &&
+                (isArray() || getSimpleBinaryName0() != null);
     }
 
     /**
@@ -1616,7 +1617,7 @@
      * @since 1.5
      */
     public boolean isMemberClass() {
-        return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
+        return !isLocalOrAnonymousClass() && getDeclaringClass0() != null;
     }
 
     /**
@@ -1626,8 +1627,7 @@
      * class.
      */
     private String getSimpleBinaryName() {
-        Class<?> enclosingClass = getEnclosingClass();
-        if (enclosingClass == null) // top level class
+        if (isTopLevelClass())
             return null;
         String name = getSimpleBinaryName0();
         if (name == null) // anonymous class
@@ -1638,6 +1638,14 @@
     private native String getSimpleBinaryName0();
 
     /**
+     * Returns {@code true} if this is a top level class.  Returns {@code false}
+     * otherwise.
+     */
+    private boolean isTopLevelClass() {
+        return !isLocalOrAnonymousClass() && getDeclaringClass0() == null;
+    }
+
+    /**
      * Returns {@code true} if this is a local class or an anonymous
      * class.  Returns {@code false} otherwise.
      */
@@ -1645,7 +1653,16 @@
         // JVM Spec 4.7.7: A class must have an EnclosingMethod
         // attribute if and only if it is a local class or an
         // anonymous class.
-        return getEnclosingMethodInfo() != null;
+        return hasEnclosingMethodInfo();
+    }
+
+    private boolean hasEnclosingMethodInfo() {
+        Object[] enclosingInfo = getEnclosingMethod0();
+        if (enclosingInfo != null) {
+            EnclosingMethodInfo.validate(enclosingInfo);
+            return true;
+        }
+        return false;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/net/Inet4Address.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/net/Inet4Address.java	Tue Dec 13 02:04:23 2016 +0100
@@ -157,7 +157,6 @@
      * address i.e first four bits of the address are 1110.
      * @return a {@code boolean} indicating if the InetAddress is
      * an IP multicast address
-     * @since   1.1
      */
     public boolean isMulticastAddress() {
         return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
@@ -167,7 +166,6 @@
      * Utility routine to check if the InetAddress is a wildcard address.
      * @return a {@code boolean} indicating if the Inetaddress is
      *         a wildcard address.
-     * @since 1.4
      */
     public boolean isAnyLocalAddress() {
         return holder().getAddress() == 0;
@@ -178,7 +176,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is
      * a loopback address; or false otherwise.
-     * @since 1.4
      */
     public boolean isLoopbackAddress() {
         /* 127.x.x.x */
@@ -191,7 +188,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is
      * a link local address; or false if address is not a link local unicast address.
-     * @since 1.4
      */
     public boolean isLinkLocalAddress() {
         // link-local unicast in IPv4 (169.254.0.0/16)
@@ -208,7 +204,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is
      * a site local address; or false if address is not a site local unicast address.
-     * @since 1.4
      */
     public boolean isSiteLocalAddress() {
         // refer to RFC 1918
@@ -229,7 +224,6 @@
      * @return a {@code boolean} indicating if the address has
      *         is a multicast address of global scope, false if it is not
      *         of global scope or it is not a multicast address
-     * @since 1.4
      */
     public boolean isMCGlobal() {
         // 224.0.1.0 to 238.255.255.255
@@ -245,7 +239,6 @@
      * @return a {@code boolean} indicating if the address has
      *         is a multicast address of node-local scope, false if it is not
      *         of node-local scope or it is not a multicast address
-     * @since 1.4
      */
     public boolean isMCNodeLocal() {
         // unless ttl == 0
@@ -258,7 +251,6 @@
      * @return a {@code boolean} indicating if the address has
      *         is a multicast address of link-local scope, false if it is not
      *         of link-local scope or it is not a multicast address
-     * @since 1.4
      */
     public boolean isMCLinkLocal() {
         // 224.0.0/24 prefix and ttl == 1
@@ -274,7 +266,6 @@
      * @return a {@code boolean} indicating if the address has
      *         is a multicast address of site-local scope, false if it is not
      *         of site-local scope or it is not a multicast address
-     * @since 1.4
      */
     public boolean isMCSiteLocal() {
         // 239.255/16 prefix or ttl < 32
@@ -290,7 +281,6 @@
      *         is a multicast address of organization-local scope,
      *         false if it is not of organization-local scope
      *         or it is not a multicast address
-     * @since 1.4
      */
     public boolean isMCOrgLocal() {
         // 239.192 - 239.195
@@ -322,7 +312,6 @@
      * Returns the IP address string in textual presentation form.
      *
      * @return  the raw IP address in a string format.
-     * @since   1.0.2
      */
     public String getHostAddress() {
         return numericToTextFormat(getAddress());
@@ -359,15 +348,14 @@
     }
 
     // Utilities
-    /*
+
+    /**
      * Converts IPv4 binary address into a string suitable for presentation.
      *
      * @param src a byte array representing an IPv4 numeric address
      * @return a String representing the IPv4 address in
      *         textual representation format
-     * @since 1.4
      */
-
     static String numericToTextFormat(byte[] src)
     {
         return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
--- a/jdk/src/java.base/share/classes/java/net/Inet6Address.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/net/Inet6Address.java	Tue Dec 13 02:04:23 2016 +0100
@@ -682,8 +682,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is an IP
      *         multicast address
-     *
-     * @since 1.1
      */
     @Override
     public boolean isMulticastAddress() {
@@ -695,8 +693,6 @@
      *
      * @return a {@code boolean} indicating if the Inetaddress is
      *         a wildcard address.
-     *
-     * @since 1.4
      */
     @Override
     public boolean isAnyLocalAddress() {
@@ -708,8 +704,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is a loopback
      *         address; or false otherwise.
-     *
-     * @since 1.4
      */
     @Override
     public boolean isLoopbackAddress() {
@@ -721,8 +715,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is a link local
      *         address; or false if address is not a link local unicast address.
-     *
-     * @since 1.4
      */
     @Override
     public boolean isLinkLocalAddress() {
@@ -740,8 +732,6 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is a site local
      *         address; or false if address is not a site local unicast address.
-     *
-     * @since 1.4
      */
     @Override
     public boolean isSiteLocalAddress() {
@@ -760,8 +750,6 @@
      * @return a {@code boolean} indicating if the address has is a multicast
      *         address of global scope, false if it is not of global scope or
      *         it is not a multicast address
-     *
-     * @since 1.4
      */
     @Override
     public boolean isMCGlobal() {
@@ -774,8 +762,6 @@
      * @return a {@code boolean} indicating if the address has is a multicast
      *         address of node-local scope, false if it is not of node-local
      *         scope or it is not a multicast address
-     *
-     * @since 1.4
      */
     @Override
     public boolean isMCNodeLocal() {
@@ -788,8 +774,6 @@
      * @return a {@code boolean} indicating if the address has is a multicast
      *         address of link-local scope, false if it is not of link-local
      *         scope or it is not a multicast address
-     *
-     * @since 1.4
      */
     @Override
     public boolean isMCLinkLocal() {
@@ -802,8 +786,6 @@
      * @return a {@code boolean} indicating if the address has is a multicast
      *         address of site-local scope, false if it is not  of site-local
      *         scope or it is not a multicast address
-     *
-     * @since 1.4
      */
     @Override
     public boolean isMCSiteLocal() {
@@ -816,8 +798,6 @@
      * @return a {@code boolean} indicating if the address has is a multicast
      *         address of organization-local scope, false if it is not of
      *         organization-local scope or it is not a multicast address
-     *
-     * @since 1.4
      */
     @Override
     public boolean isMCOrgLocal() {
@@ -914,23 +894,21 @@
      *
      * @return a {@code boolean} indicating if the InetAddress is an IPv4
      *         compatible IPv6 address; or false if address is IPv4 address.
-     *
-     * @since 1.4
      */
     public boolean isIPv4CompatibleAddress() {
         return holder6.isIPv4CompatibleAddress();
     }
 
     // Utilities
+
     private static final int INT16SZ = 2;
 
-    /*
+    /**
      * Convert IPv6 binary address into presentation (printable) format.
      *
      * @param src a byte array representing the IPv6 numeric address
      * @return a String representing an IPv6 address in
      *         textual representation format
-     * @since 1.4
      */
     static String numericToTextFormat(byte[] src) {
         StringBuilder sb = new StringBuilder(39);
--- a/jdk/src/java.base/share/classes/java/util/Collections.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Collections.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -4699,8 +4699,8 @@
             public void forEachRemaining(Consumer<? super E> action) {
                 Objects.requireNonNull(action);
                 if (hasNext) {
+                    hasNext = false;
                     action.accept(e);
-                    hasNext = false;
                 }
             }
         };
--- a/jdk/src/java.base/share/classes/java/util/Locale.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java	Tue Dec 13 02:04:23 2016 +0100
@@ -46,6 +46,7 @@
 import java.io.ObjectStreamField;
 import java.io.Serializable;
 import java.text.MessageFormat;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.spi.LocaleNameProvider;
 
 import sun.security.action.GetPropertyAction;
@@ -600,6 +601,68 @@
     static final long serialVersionUID = 9149081749638150636L;
 
     /**
+     * Enum for specifying the type defined in ISO 3166. This enum is used to
+     * retrieve the two-letter ISO3166-1 alpha-2, three-letter ISO3166-1
+     * alpha-3, four-letter ISO3166-3 country codes.
+     *
+     * @see #getISOCountries(Locale.IsoCountryCode)
+     * @since 9
+     */
+    public static enum IsoCountryCode {
+        /**
+         * PART1_ALPHA2 is used to represent the ISO3166-1 alpha-2 two letter
+         * country codes.
+         */
+        PART1_ALPHA2 {
+            @Override
+            Set<String> createCountryCodeSet() {
+                return Set.of(Locale.getISOCountries());
+            }
+        },
+
+        /**
+         *
+         * PART1_ALPHA3 is used to represent the ISO3166-1 alpha-3 three letter
+         * country codes.
+         */
+        PART1_ALPHA3 {
+            @Override
+            Set<String> createCountryCodeSet() {
+                return LocaleISOData.computeISO3166_1Alpha3Countries();
+            }
+        },
+
+        /**
+         * PART3 is used to represent the ISO3166-3 four letter country codes.
+         */
+        PART3 {
+            @Override
+            Set<String> createCountryCodeSet() {
+                return Set.of(LocaleISOData.ISO3166_3);
+            }
+        };
+
+        /**
+         * Concrete implementation of this method attempts to compute value
+         * for iso3166CodesMap for each IsoCountryCode type key.
+         */
+        abstract Set<String> createCountryCodeSet();
+
+        /**
+         * Map to hold country codes for each ISO3166 part.
+         */
+        private static Map<IsoCountryCode, Set<String>> iso3166CodesMap = new ConcurrentHashMap<>();
+
+        /**
+         * This method is called from Locale class to retrieve country code set
+         * for getISOCountries(type)
+         */
+        static Set<String> retrieveISOCountryCodes(IsoCountryCode type) {
+            return iso3166CodesMap.computeIfAbsent(type, IsoCountryCode::createCountryCodeSet);
+        }
+    }
+
+    /**
      * Display types for retrieving localized names from the name providers.
      */
     private static final int DISPLAY_LANGUAGE = 0;
@@ -996,12 +1059,18 @@
     /**
      * Returns a list of all 2-letter country codes defined in ISO 3166.
      * Can be used to create Locales.
+     * This method is equivalent to {@link #getISOCountries(Locale.IsoCountryCode type)}
+     * with {@code type}  {@link IsoCountryCode#PART1_ALPHA2}.
      * <p>
      * <b>Note:</b> The <code>Locale</code> class also supports other codes for
      * country (region), such as 3-letter numeric UN M.49 area codes.
      * Therefore, the list returned by this method does not contain ALL valid
      * codes that can be used to create Locales.
-     *
+     * <p>
+     * Note that this method does not return obsolete 2-letter country codes.
+     * ISO3166-3 codes which designate country codes for those obsolete codes,
+     * can be retrieved from {@link #getISOCountries(Locale.IsoCountryCode type)} with
+     * {@code type}  {@link IsoCountryCode#PART3}.
      * @return An array of ISO 3166 two-letter country codes.
      */
     public static String[] getISOCountries() {
@@ -1014,6 +1083,20 @@
     }
 
     /**
+     * Returns a {@code Set} of ISO3166 country codes for the specified type.
+     *
+     * @param type {@link Locale.IsoCountryCode} specified ISO code type.
+     * @see java.util.Locale.IsoCountryCode
+     * @throws NullPointerException if type is null
+     * @return a {@code Set} of ISO country codes for the specified type.
+     * @since 9
+     */
+    public static Set<String> getISOCountries(IsoCountryCode type) {
+        Objects.requireNonNull(type);
+        return IsoCountryCode.retrieveISOCountryCodes(type);
+    }
+
+    /**
      * Returns a list of all 2-letter language codes defined in ISO 639.
      * Can be used to create Locales.
      * <p>
--- a/jdk/src/java.base/share/classes/java/util/LocaleISOData.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/LocaleISOData.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -231,7 +231,7 @@
         + "AI" + "AIA"  // Anguilla
         + "AL" + "ALB"  // Albania, People's Socialist Republic of
         + "AM" + "ARM"  // Armenia
-        + "AN" + "ANT"  // Netherlands Antilles
+//      + "AN" + "ANT"  // Netherlands Antilles
         + "AO" + "AGO"  // Angola, Republic of
         + "AQ" + "ATA"  // Antarctica (the territory South of 60 deg S)
         + "AR" + "ARG"  // Argentina, Argentine Republic
@@ -477,6 +477,29 @@
         + "ZW" + "ZWE"  // Zimbabwe
         ;
 
+    /**
+     * Array to hold country codes for ISO3166-3.
+     */
+    static final String[] ISO3166_3 = {
+        "AIDJ", "ANHH", "BQAQ", "BUMM", "BYAA", "CSHH", "CSXX", "CTKI", "DDDE",
+        "DYBJ", "FQHH", "FXFR", "GEHH", "HVBF", "JTUM", "MIUM", "NHVU", "NQAQ",
+        "NTHH", "PCHH", "PUUM", "PZPA", "RHZW", "SKIN", "SUHH", "TPTL", "VDVN",
+        "WKUM", "YDYE", "YUCS", "ZRCD"
+    };
+
+    /**
+     * This method computes a set of ISO3166-1 alpha-3 country codes from
+     * existing isoCountryTable.
+     */
+    static Set<String> computeISO3166_1Alpha3Countries() {
+        int tableLength = isoCountryTable.length();
+        String[] isoTable = new String[tableLength / 5];
+        for (int i = 0, index = 0; index < tableLength; i++, index += 5) {
+            isoTable[i] = isoCountryTable.substring(index + 2, index + 5);
+        }
+        return Set.of(isoTable);
+    }
+
     private LocaleISOData() {
     }
 }
--- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java	Tue Dec 13 02:04:23 2016 +0100
@@ -650,6 +650,7 @@
         private Locale locale;
         private KeyElementReference<ClassLoader> loaderRef;
         private KeyElementReference<Module> moduleRef;
+        private KeyElementReference<Module> callerRef;
 
 
         // bundle format which is necessary for calling
@@ -680,7 +681,7 @@
         // Boolean.TRUE if the factory method caller provides a ResourceBundleProvier.
         private Boolean callerHasProvider;
 
-        CacheKey(String baseName, Locale locale, ClassLoader loader, Module module) {
+        CacheKey(String baseName, Locale locale, ClassLoader loader, Module module, Module caller) {
             Objects.requireNonNull(module);
 
             this.name = baseName;
@@ -691,6 +692,8 @@
                 this.loaderRef = new KeyElementReference<>(loader, referenceQueue, this);
             }
             this.moduleRef = new KeyElementReference<>(module, referenceQueue, this);
+            this.callerRef = new KeyElementReference<>(caller, referenceQueue, this);
+
             calculateHashCode();
         }
 
@@ -726,6 +729,10 @@
             return moduleRef.get();
         }
 
+        Module getCallerModule() {
+            return callerRef.get();
+        }
+
         ServiceLoader<ResourceBundleProvider> getProviders() {
             if (!providersChecked) {
                 providers = getServiceLoader(getModule(), name);
@@ -767,6 +774,8 @@
                 }
                 ClassLoader loader = getLoader();
                 Module module = getModule();
+                Module caller = getCallerModule();
+
                 return (otherEntry.loaderRef != null)
                         // with a null reference we can no longer find
                         // out which class loader or module was referenced; so
@@ -774,7 +783,9 @@
                         && (loader != null)
                         && (loader == otherEntry.getLoader())
                         && (module != null)
-                        && (module.equals(otherEntry.getModule()));
+                        && (module.equals(otherEntry.getModule()))
+                        && (caller != null)
+                        && (caller.equals(otherEntry.getCallerModule()));
             } catch (NullPointerException | ClassCastException e) {
             }
             return false;
@@ -796,6 +807,10 @@
             if (module != null) {
                 hashCodeCache ^= module.hashCode();
             }
+            Module caller = getCallerModule();
+            if (caller != null) {
+                hashCodeCache ^= caller.hashCode();
+            }
         }
 
         @Override
@@ -808,6 +823,9 @@
                 }
                 clone.moduleRef = new KeyElementReference<>(getModule(),
                                                             referenceQueue, clone);
+                clone.callerRef = new KeyElementReference<>(getCallerModule(),
+                                                            referenceQueue, clone);
+
                 // Clear the reference to ResourceBundleProviders and the flag
                 clone.providers = null;
                 clone.providersChecked = false;
@@ -1665,7 +1683,7 @@
         // loader, and module will never change during the bundle loading
         // process. We have to make sure that the locale is set before
         // using it as a cache key.
-        CacheKey cacheKey = new CacheKey(baseName, locale, loader, module);
+        CacheKey cacheKey = new CacheKey(baseName, locale, loader, module, callerModule);
         ResourceBundle bundle = null;
 
         // Quick lookup of the cache.
@@ -1869,7 +1887,7 @@
                     bundle = loadBundleFromProviders(baseName,
                                                      targetLocale,
                                                      cacheKey.getProviders(),
-                                                      cacheKey);
+                                                     cacheKey);
                 }
             }
 
@@ -2303,8 +2321,9 @@
 
     private static void clearCache(ClassLoader loader, Module module) {
         Set<CacheKey> set = cacheList.keySet();
-        set.stream().filter((key) -> (key.getLoader() == loader && key.getModule() == module))
-                .forEach(set::remove);
+        set.stream()
+           .filter((key) -> (key.getLoader() == loader && key.getModule() == module))
+           .forEach(set::remove);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java	Tue Dec 13 02:04:23 2016 +0100
@@ -65,36 +65,37 @@
  * common mutable reduction tasks:
  *
  * <pre>{@code
- *     // Accumulate names into a List
- *     List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
- *
- *     // Accumulate names into a TreeSet
- *     Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
+ * // Accumulate names into a List
+ * List<String> list = people.stream()
+ *   .map(Person::getName)
+ *   .collect(Collectors.toList());
  *
- *     // Convert elements to strings and concatenate them, separated by commas
- *     String joined = things.stream()
- *                           .map(Object::toString)
- *                           .collect(Collectors.joining(", "));
+ * // Accumulate names into a TreeSet
+ * Set<String> set = people.stream()
+ *   .map(Person::getName)
+ *   .collect(Collectors.toCollection(TreeSet::new));
  *
- *     // Compute sum of salaries of employee
- *     int total = employees.stream()
- *                          .collect(Collectors.summingInt(Employee::getSalary)));
+ * // Convert elements to strings and concatenate them, separated by commas
+ * String joined = things.stream()
+ *   .map(Object::toString)
+ *   .collect(Collectors.joining(", "));
  *
- *     // Group employees by department
- *     Map<Department, List<Employee>> byDept
- *         = employees.stream()
- *                    .collect(Collectors.groupingBy(Employee::getDepartment));
+ * // Compute sum of salaries of employee
+ * int total = employees.stream()
+ *   .collect(Collectors.summingInt(Employee::getSalary));
+ *
+ * // Group employees by department
+ * Map<Department, List<Employee>> byDept = employees.stream()
+ *   .collect(Collectors.groupingBy(Employee::getDepartment));
  *
- *     // Compute sum of salaries by department
- *     Map<Department, Integer> totalByDept
- *         = employees.stream()
- *                    .collect(Collectors.groupingBy(Employee::getDepartment,
- *                                                   Collectors.summingInt(Employee::getSalary)));
+ * // Compute sum of salaries by department
+ * Map<Department, Integer> totalByDept = employees.stream()
+ *   .collect(Collectors.groupingBy(Employee::getDepartment,
+ *                                  Collectors.summingInt(Employee::getSalary)));
  *
- *     // Partition students into passing and failing
- *     Map<Boolean, List<Student>> passingFailing =
- *         students.stream()
- *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
+ * // Partition students into passing and failing
+ * Map<Boolean, List<Student>> passingFailing = students.stream()
+ *   .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
  *
  * }</pre>
  *
@@ -248,8 +249,8 @@
      *
      * @param <T> the type of the input elements
      * @param <C> the type of the resulting {@code Collection}
-     * @param collectionFactory a {@code Supplier} which returns a new, empty
-     * {@code Collection} of the appropriate type
+     * @param collectionFactory a supplier providing a new empty {@code Collection}
+     *                          into which the results will be inserted
      * @return a {@code Collector} which collects all the input elements into a
      * {@code Collection}, in encounter order
      */
@@ -384,9 +385,11 @@
      * {@code partitioningBy}.  For example, given a stream of
      * {@code Person}, to accumulate the set of last names in each city:
      * <pre>{@code
-     *     Map<City, Set<String>> lastNamesByCity
-     *         = people.stream().collect(groupingBy(Person::getCity,
-     *                                              mapping(Person::getLastName, toSet())));
+     * Map<City, Set<String>> lastNamesByCity
+     *   = people.stream().collect(
+     *     groupingBy(Person::getCity,
+     *                mapping(Person::getLastName,
+     *                        toSet())));
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -424,9 +427,11 @@
      * {@code partitioningBy}.  For example, given a stream of
      * {@code Order}, to accumulate the set of line items for each customer:
      * <pre>{@code
-     *     Map<String, Set<LineItem>> itemsByCustomerName
-     *         = orders.stream().collect(groupingBy(Order::getCustomerName,
-     *                                              flatMapping(order -> order.getLineItems().stream(), toSet())));
+     * Map<String, Set<LineItem>> itemsByCustomerName
+     *   = orders.stream().collect(
+     *     groupingBy(Order::getCustomerName,
+     *                flatMapping(order -> order.getLineItems().stream(),
+     *                            toSet())));
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -468,9 +473,11 @@
      * {@code Employee}, to accumulate the employees in each department that have a
      * salary above a certain threshold:
      * <pre>{@code
-     *     Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
-     *         = employees.stream().collect(groupingBy(Employee::getDepartment,
-     *                                              filtering(e -> e.getSalary() > 2000, toSet())));
+     * Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
+     *   = employees.stream().collect(
+     *     groupingBy(Employee::getDepartment,
+     *                filtering(e -> e.getSalary() > 2000,
+     *                          toSet())));
      * }</pre>
      * A filtering collector differs from a stream's {@code filter()} operation.
      * In this example, suppose there are no employees whose salary is above the
@@ -491,7 +498,7 @@
      */
     public static <T, A, R>
     Collector<T, ?, R> filtering(Predicate<? super T> predicate,
-                               Collector<? super T, A, R> downstream) {
+                                 Collector<? super T, A, R> downstream) {
         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
         return new CollectorImpl<>(downstream.supplier(),
                                    (r, t) -> {
@@ -508,8 +515,9 @@
      * transformation.  For example, one could adapt the {@link #toList()}
      * collector to always produce an immutable list with:
      * <pre>{@code
-     *     List<String> list
-     *         = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList));
+     * List<String> list = people.stream().collect(
+     *   collectingAndThen(toList(),
+     *                     Collections::unmodifiableList));
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -829,9 +837,11 @@
      * <p>For example, given a stream of {@code Person}, to calculate tallest
      * person in each city:
      * <pre>{@code
-     *     Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
-     *     Map<City, Optional<Person>> tallestByCity
-     *         = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));
+     * Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
+     * Map<City, Optional<Person>> tallestByCity
+     *   = people.stream().collect(
+     *     groupingBy(Person::getCity,
+     *                reducing(BinaryOperator.maxBy(byHeight))));
      * }</pre>
      *
      * @param <T> element type for the input and output of the reduction
@@ -882,10 +892,13 @@
      * <p>For example, given a stream of {@code Person}, to calculate the longest
      * last name of residents in each city:
      * <pre>{@code
-     *     Comparator<String> byLength = Comparator.comparing(String::length);
-     *     Map<City, String> longestLastNameByCity
-     *         = people.stream().collect(groupingBy(Person::getCity,
-     *                                              reducing("", Person::getLastName, BinaryOperator.maxBy(byLength))));
+     * Comparator<String> byLength = Comparator.comparing(String::length);
+     * Map<City, String> longestLastNameByCity
+     *   = people.stream().collect(
+     *     groupingBy(Person::getCity,
+     *                reducing("",
+     *                         Person::getLastName,
+     *                         BinaryOperator.maxBy(byLength))));
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -969,9 +982,11 @@
      *
      * <p>For example, to compute the set of last names of people in each city:
      * <pre>{@code
-     *     Map<City, Set<String>> namesByCity
-     *         = people.stream().collect(groupingBy(Person::getCity,
-     *                                              mapping(Person::getLastName, toSet())));
+     * Map<City, Set<String>> namesByCity
+     *   = people.stream().collect(
+     *     groupingBy(Person::getCity,
+     *                mapping(Person::getLastName,
+     *                        toSet())));
      * }</pre>
      *
      * @implNote
@@ -1016,9 +1031,12 @@
      * <p>For example, to compute the set of last names of people in each city,
      * where the city names are sorted:
      * <pre>{@code
-     *     Map<City, Set<String>> namesByCity
-     *         = people.stream().collect(groupingBy(Person::getCity, TreeMap::new,
-     *                                              mapping(Person::getLastName, toSet())));
+     * Map<City, Set<String>> namesByCity
+     *   = people.stream().collect(
+     *     groupingBy(Person::getCity,
+     *                TreeMap::new,
+     *                mapping(Person::getLastName,
+     *                        toSet())));
      * }</pre>
      *
      * @implNote
@@ -1036,8 +1054,8 @@
      * @param <M> the type of the resulting {@code Map}
      * @param classifier a classifier function mapping input elements to keys
      * @param downstream a {@code Collector} implementing the downstream reduction
-     * @param mapFactory a function which, when called, produces a new empty
-     *                   {@code Map} of the desired type
+     * @param mapFactory a supplier providing a new empty {@code Map}
+     *                   into which the results will be inserted
      * @return a {@code Collector} implementing the cascaded group-by operation
      *
      * @see #groupingBy(Function, Collector)
@@ -1127,7 +1145,7 @@
      * <p>The classification function maps elements to some key type {@code K}.
      * The downstream collector operates on elements of type {@code T} and
      * produces a result of type {@code D}. The resulting collector produces a
-     * {@code Map<K, D>}.
+     * {@code ConcurrentMap<K, D>}.
      *
      * <p>There are no guarantees on the type, mutability, or serializability
      * of the {@code ConcurrentMap} returned.
@@ -1135,9 +1153,11 @@
      * <p>For example, to compute the set of last names of people in each city,
      * where the city names are sorted:
      * <pre>{@code
-     *     ConcurrentMap<City, Set<String>> namesByCity
-     *         = people.stream().collect(groupingByConcurrent(Person::getCity,
-     *                                                        mapping(Person::getLastName, toSet())));
+     * ConcurrentMap<City, Set<String>> namesByCity
+     *   = people.stream().collect(
+     *     groupingByConcurrent(Person::getCity,
+     *                          mapping(Person::getLastName,
+     *                                  toSet())));
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -1172,17 +1192,19 @@
      * <p>The classification function maps elements to some key type {@code K}.
      * The downstream collector operates on elements of type {@code T} and
      * produces a result of type {@code D}. The resulting collector produces a
-     * {@code Map<K, D>}.
+     * {@code ConcurrentMap<K, D>}.
      *
      * <p>For example, to compute the set of last names of people in each city,
      * where the city names are sorted:
      * <pre>{@code
-     *     ConcurrentMap<City, Set<String>> namesByCity
-     *         = people.stream().collect(groupingBy(Person::getCity, ConcurrentSkipListMap::new,
-     *                                              mapping(Person::getLastName, toSet())));
+     * ConcurrentMap<City, Set<String>> namesByCity
+     *   = people.stream().collect(
+     *     groupingByConcurrent(Person::getCity,
+     *                          ConcurrentSkipListMap::new,
+     *                          mapping(Person::getLastName,
+     *                                  toSet())));
      * }</pre>
      *
-     *
      * @param <T> the type of the input elements
      * @param <K> the type of the keys
      * @param <A> the intermediate accumulation type of the downstream collector
@@ -1190,8 +1212,8 @@
      * @param <M> the type of the resulting {@code ConcurrentMap}
      * @param classifier a classifier function mapping input elements to keys
      * @param downstream a {@code Collector} implementing the downstream reduction
-     * @param mapFactory a function which, when called, produces a new empty
-     *                   {@code ConcurrentMap} of the desired type
+     * @param mapFactory a supplier providing a new empty {@code ConcurrentMap}
+     *                   into which the results will be inserted
      * @return a concurrent, unordered {@code Collector} implementing the cascaded group-by operation
      *
      * @see #groupingByConcurrent(Function)
@@ -1311,7 +1333,7 @@
      * {@code Map} whose keys and values are the result of applying the provided
      * mapping functions to the input elements.
      *
-     * <p>If the mapped keys contains duplicates (according to
+     * <p>If the mapped keys contain duplicates (according to
      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
      * thrown when the collection operation is performed.  If the mapped keys
      * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
@@ -1327,16 +1349,18 @@
      * For example, the following produces a {@code Map} mapping
      * students to their grade point average:
      * <pre>{@code
-     *     Map<Student, Double> studentToGPA
-     *         students.stream().collect(toMap(Function.identity(),
-     *                                         student -> computeGPA(student)));
+     * Map<Student, Double> studentToGPA
+     *   = students.stream().collect(
+     *     toMap(Function.identity(),
+     *           student -> computeGPA(student)));
      * }</pre>
      * And the following produces a {@code Map} mapping a unique identifier to
      * students:
      * <pre>{@code
-     *     Map<String, Student> studentIdToStudent
-     *         students.stream().collect(toMap(Student::getId,
-     *                                         Function.identity());
+     * Map<String, Student> studentIdToStudent
+     *   = students.stream().collect(
+     *     toMap(Student::getId,
+     *           Function.identity()));
      * }</pre>
      *
      * @implNote
@@ -1375,7 +1399,7 @@
      * mapping functions to the input elements.
      *
      * <p>If the mapped
-     * keys contains duplicates (according to {@link Object#equals(Object)}),
+     * keys contain duplicates (according to {@link Object#equals(Object)}),
      * the value mapping function is applied to each equal element, and the
      * results are merged using the provided merging function.
      *
@@ -1389,13 +1413,14 @@
      * more flexible merge policies.  For example, if you have a stream
      * of {@code Person}, and you want to produce a "phone book" mapping name to
      * address, but it is possible that two persons have the same name, you can
-     * do as follows to gracefully deals with these collisions, and produce a
+     * do as follows to gracefully deal with these collisions, and produce a
      * {@code Map} mapping names to a concatenated list of addresses:
      * <pre>{@code
-     *     Map<String, String> phoneBook
-     *         people.stream().collect(toMap(Person::getName,
-     *                                       Person::getAddress,
-     *                                       (s, a) -> s + ", " + a));
+     * Map<String, String> phoneBook
+     *   = people.stream().collect(
+     *     toMap(Person::getName,
+     *           Person::getAddress,
+     *           (s, a) -> s + ", " + a));
      * }</pre>
      *
      * @implNote
@@ -1437,7 +1462,7 @@
      * mapping functions to the input elements.
      *
      * <p>If the mapped
-     * keys contains duplicates (according to {@link Object#equals(Object)}),
+     * keys contain duplicates (according to {@link Object#equals(Object)}),
      * the value mapping function is applied to each equal element, and the
      * results are merged using the provided merging function.  The {@code Map}
      * is created by a provided supplier function.
@@ -1459,8 +1484,8 @@
      * @param mergeFunction a merge function, used to resolve collisions between
      *                      values associated with the same key, as supplied
      *                      to {@link Map#merge(Object, Object, BiFunction)}
-     * @param mapSupplier a function which returns a new, empty {@code Map} into
-     *                    which the results will be inserted
+     * @param mapFactory a supplier providing a new empty {@code Map}
+     *                   into which the results will be inserted
      * @return a {@code Collector} which collects elements into a {@code Map}
      * whose keys are the result of applying a key mapping function to the input
      * elements, and whose values are the result of applying a value mapping
@@ -1473,13 +1498,13 @@
      */
     public static <T, K, U, M extends Map<K, U>>
     Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
-                                Function<? super T, ? extends U> valueMapper,
-                                BinaryOperator<U> mergeFunction,
-                                Supplier<M> mapSupplier) {
+                             Function<? super T, ? extends U> valueMapper,
+                             BinaryOperator<U> mergeFunction,
+                             Supplier<M> mapFactory) {
         BiConsumer<M, T> accumulator
                 = (map, element) -> map.merge(keyMapper.apply(element),
                                               valueMapper.apply(element), mergeFunction);
-        return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
+        return new CollectorImpl<>(mapFactory, accumulator, mapMerger(mergeFunction), CH_ID);
     }
 
     /**
@@ -1487,7 +1512,7 @@
      * {@code ConcurrentMap} whose keys and values are the result of applying
      * the provided mapping functions to the input elements.
      *
-     * <p>If the mapped keys contains duplicates (according to
+     * <p>If the mapped keys contain duplicates (according to
      * {@link Object#equals(Object)}), an {@code IllegalStateException} is
      * thrown when the collection operation is performed.  If the mapped keys
      * may have duplicates, use
@@ -1500,19 +1525,21 @@
      * It is common for either the key or the value to be the input elements.
      * In this case, the utility method
      * {@link java.util.function.Function#identity()} may be helpful.
-     * For example, the following produces a {@code Map} mapping
+     * For example, the following produces a {@code ConcurrentMap} mapping
      * students to their grade point average:
      * <pre>{@code
-     *     Map<Student, Double> studentToGPA
-     *         students.stream().collect(toMap(Function.identity(),
-     *                                         student -> computeGPA(student)));
+     * ConcurrentMap<Student, Double> studentToGPA
+     *   = students.stream().collect(
+     *     toConcurrentMap(Function.identity(),
+     *                     student -> computeGPA(student)));
      * }</pre>
-     * And the following produces a {@code Map} mapping a unique identifier to
-     * students:
+     * And the following produces a {@code ConcurrentMap} mapping a
+     * unique identifier to students:
      * <pre>{@code
-     *     Map<String, Student> studentIdToStudent
-     *         students.stream().collect(toConcurrentMap(Student::getId,
-     *                                                   Function.identity());
+     * ConcurrentMap<String, Student> studentIdToStudent
+     *   = students.stream().collect(
+     *     toConcurrentMap(Student::getId,
+     *                     Function.identity()));
      * }</pre>
      *
      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
@@ -1546,7 +1573,7 @@
      * {@code ConcurrentMap} whose keys and values are the result of applying
      * the provided mapping functions to the input elements.
      *
-     * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
+     * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
      * the value mapping function is applied to each equal element, and the
      * results are merged using the provided merging function.
      *
@@ -1560,13 +1587,14 @@
      * more flexible merge policies.  For example, if you have a stream
      * of {@code Person}, and you want to produce a "phone book" mapping name to
      * address, but it is possible that two persons have the same name, you can
-     * do as follows to gracefully deals with these collisions, and produce a
-     * {@code Map} mapping names to a concatenated list of addresses:
+     * do as follows to gracefully deal with these collisions, and produce a
+     * {@code ConcurrentMap} mapping names to a concatenated list of addresses:
      * <pre>{@code
-     *     Map<String, String> phoneBook
-     *         people.stream().collect(toConcurrentMap(Person::getName,
-     *                                                 Person::getAddress,
-     *                                                 (s, a) -> s + ", " + a));
+     * ConcurrentMap<String, String> phoneBook
+     *   = people.stream().collect(
+     *     toConcurrentMap(Person::getName,
+     *                     Person::getAddress,
+     *                     (s, a) -> s + ", " + a));
      * }</pre>
      *
      * <p>This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
@@ -1603,7 +1631,7 @@
      * {@code ConcurrentMap} whose keys and values are the result of applying
      * the provided mapping functions to the input elements.
      *
-     * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}),
+     * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}),
      * the value mapping function is applied to each equal element, and the
      * results are merged using the provided merging function.  The
      * {@code ConcurrentMap} is created by a provided supplier function.
@@ -1620,8 +1648,8 @@
      * @param mergeFunction a merge function, used to resolve collisions between
      *                      values associated with the same key, as supplied
      *                      to {@link Map#merge(Object, Object, BiFunction)}
-     * @param mapSupplier a function which returns a new, empty {@code Map} into
-     *                    which the results will be inserted
+     * @param mapFactory a supplier providing a new empty {@code ConcurrentMap}
+     *                   into which the results will be inserted
      * @return a concurrent, unordered {@code Collector} which collects elements into a
      * {@code ConcurrentMap} whose keys are the result of applying a key mapping
      * function to the input elements, and whose values are the result of
@@ -1636,11 +1664,11 @@
     Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
                                        Function<? super T, ? extends U> valueMapper,
                                        BinaryOperator<U> mergeFunction,
-                                       Supplier<M> mapSupplier) {
+                                       Supplier<M> mapFactory) {
         BiConsumer<M, T> accumulator
                 = (map, element) -> map.merge(keyMapper.apply(element),
                                               valueMapper.apply(element), mergeFunction);
-        return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_CONCURRENT_ID);
+        return new CollectorImpl<>(mapFactory, accumulator, mapMerger(mergeFunction), CH_CONCURRENT_ID);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java	Tue Dec 13 02:04:23 2016 +0100
@@ -331,7 +331,9 @@
         ZipFileInputStream in = null;
         synchronized (this) {
             ensureOpen();
-            if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
+            if (Objects.equals(lastEntryName, entry.name)) {
+                pos = lastEntryPos;
+            } else if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
                 pos = zsrc.getEntryPos(zc.getBytesUTF8(entry.name), false);
             } else {
                 pos = zsrc.getEntryPos(zc.getBytes(entry.name), false);
@@ -526,6 +528,9 @@
                         Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
     }
 
+    private String lastEntryName;
+    private int lastEntryPos;
+
     /* Checks ensureOpen() before invoke this method */
     private ZipEntry getZipEntry(String name, byte[] bname, int pos) {
         byte[] cen = zsrc.cen;
@@ -563,6 +568,8 @@
                 e.comment = zc.toString(cen, start, clen);
             }
         }
+        lastEntryName = e.name;
+        lastEntryPos = pos;
         return e;
     }
 
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java	Tue Dec 13 02:04:23 2016 +0100
@@ -28,8 +28,10 @@
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Iterator;
 import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -39,9 +41,9 @@
  */
 public class JmodFile implements AutoCloseable {
     // jmod magic number and version number
-    public static final int JMOD_MAJOR_VERSION = 0x01;
-    public static final int JMOD_MINOR_VERSION = 0x00;
-    public static final byte[] JMOD_MAGIC_NUMBER = {
+    private static final int JMOD_MAJOR_VERSION = 0x01;
+    private static final int JMOD_MINOR_VERSION = 0x00;
+    private static final byte[] JMOD_MAGIC_NUMBER = {
         0x4A, 0x4D, /* JM */
         JMOD_MAJOR_VERSION, JMOD_MINOR_VERSION, /* version 1.0 */
     };
@@ -175,6 +177,10 @@
         this.zipfile = new ZipFile(file.toFile());
     }
 
+    public static void writeMagicNumber(OutputStream os) throws IOException {
+        os.write(JMOD_MAGIC_NUMBER);
+    }
+
     /**
      * Returns the {@code Entry} for a resource in a JMOD file section
      * or {@code null} if not found.
--- a/jdk/src/java.base/share/classes/module-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -156,6 +156,7 @@
     exports jdk.internal.misc to
         java.corba,
         java.desktop,
+        jdk.incubator.httpclient,
         java.logging,
         java.management,
         java.naming,
@@ -199,7 +200,7 @@
         java.management,
         jdk.jvmstat;
     exports sun.net to
-        java.httpclient;
+        jdk.incubator.httpclient;
     exports sun.net.ext to
         jdk.net;
     exports sun.net.dns to
@@ -210,6 +211,7 @@
         jdk.jconsole,
         jdk.naming.dns;
     exports sun.net.www to
+        jdk.incubator.httpclient,
         java.desktop,
         jdk.jartool;
     exports sun.net.www.protocol.http to
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_de.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_de.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   Verwendung: {0} [options] class [args...]\n           (zur Ausf\u00FChrung einer Klasse)\n   oder  {0} [options] -jar jarfile [args...]\n           (zur Ausf\u00FChrung einer JAR-Datei)\n   oder  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (zur Ausf\u00FChrung der Hauptklasse in einem Modul)\nwobei "options" Folgendes umfasst:\n
+java.launcher.opt.header  =   Verwendung: {0} [Optionen] Klasse [Argumente...]\n           (zur Ausf\u00FChrung einer Klasse)\n   oder  {0} [Optionen] -jar JAR-Datei [Argumente...]\n           (zur Ausf\u00FChrung einer JAR-Datei)\n   oder  {0} [Optionen] -p <Modulpfad> -m <Modulname>[/<Hauptklasse>] [Argumente...]\n           (zur Ausf\u00FChrung der Hauptklasse in einem Modul)\nwobei "Optionen" Folgendes umfasst:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  Verwendet ein {0}-Bit-Datenmodell, sofern verf\u00FCgbar\n
+java.launcher.opt.datamodel  =\    -d{0}\t  Veraltet, wird in einem zuk\u00FCnftigen Release entfernt\n
 java.launcher.opt.vmselect   =\    {0}\t  zur Auswahl der "{1}" VM\n
 java.launcher.opt.hotspot    =\    {0}\t  ist ein Synonym f\u00FCr die "{1}" VM  [verworfen]\n
 
@@ -34,11 +34,11 @@
 java.launcher.ergo.message2  =\                  weil die Ausf\u00FChrung auf einem Server-Class-Rechner erfolgt.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =-cp <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n    -classpath <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n                  und ZIP-Archiven zur Suche nach Klassendateien.\n    -mp <Modulpfad>\n    -modulepath <Modulpfad>...\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, in der jedes Verzeichnis\n                  ein Modulverzeichnis darstellt.\n    -upgrademodulepath <Modulpfad>...\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, in der jedes Verzeichnis\n                  ein Verzeichnis von Modulen darstellt, die upgradef\u00E4hige\n                  Module im Laufzeitimage ersetzen\n    -m <modulename>[/<mainclass>]\n                  Das aufzul\u00F6sende anf\u00E4ngliche Modul und der Name der auszuf\u00FChrenden Hauptklasse,\n                  wenn nicht durch das Modul angegeben\n    -addmods <modulename>[,<modulename>...]\n                  Root-Module, die zus\u00E4tzlich zum anf\u00E4nglichen Modul aufgel\u00F6st werden sollen\n    -limitmods <modulename>[,<modulename>...]\n                  Gesamtzahl der beobachtbaren Module einschr\u00E4nken\n    -listmods[:<modulename>[,<modulename>...]]\n                  Beobachtbare Module auflisten und Vorgang beenden\n    --dry-run     VM erstellen, aber Hauptmethode nicht ausf\u00FChren.\n                  Diese dry-run-Option kann n\u00FCtzlich sein, um\n                  Befehlszeilenoptionen wie die Modulsystemkonfiguration zu validieren.\n    -D<name>=<value>\n                  Systemeigenschaft festlegen\n    -verbose:[class|gc|jni]\n                  Verbose-Ausgabe aktivieren\n    -version      Produktversion drucken und Vorgang beenden\n    -showversion  Produktversion drucken und fortfahren\n    -? -help      Diese Hilfemeldung drucken\n    -X            Hilfe zu Nicht-Standardoptionen drucken\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  Assertions mit angegebener Granularit\u00E4t aktivieren\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  Assertions mit angegebener Granularit\u00E4t deaktivieren\n    -esa | -enablesystemassertions\n                  System-Assertions aktivieren\n    -dsa | -disablesystemassertions\n                  System-Assertions deaktivieren\n    -agentlib:<libname>[=<options>]\n                  Native Agent Library <libname> laden, z.\u00A0B. -agentlib:jdwp,\n                  siehe auch -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  Native Agent Library nach vollst\u00E4ndigem Pfadnamen laden\n    -javaagent:<jarpath>[=<options>]\n                  Agent f\u00FCr Java-Programmiersprachen laden, siehe java.lang.instrument\n    -splash:<imagepath>\n                  Startbildschirm mit angegebenem Bild anzeigen\n    @<filepath>   Optionen aus der angegebenen Datei lesen\n
+java.launcher.opt.footer     =\    -cp <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n    -classpath <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n    --class-path <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n                  und ZIP-Archiven zur Suche nach Klassendateien.\n    -p <Modulpfad>\n    --module-path <Modulpfad>...\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, wobei jedes Verzeichnis\n                  ein Modulverzeichnis ist.\n    --upgrade-module-path <Modulpfad>...\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, wobei jedes Verzeichnis\n                  ein Verzeichnis mit Modulen ist, die upgradef\u00E4hige\n                  Module im Laufzeitimage ersetzen\n    -m <Modul>[/<Hauptklasse>]\n    --module <Modulname>[/<Hauptklasse>]\n                  Das anf\u00E4ngliche aufzul\u00F6sende Modul und der Name der auszuf\u00FChrenden\n                  Hauptklasse, wenn nicht durch das Modul angegeben\n    --add-modules <Modulname>[,<Modulname>...]\n                  Zus\u00E4tzlich zu dem anf\u00E4nglichen Modul aufzul\u00F6sende Root-Module.\n                  <Modulname> kann auch ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH sein.\n    --limit-modules <Modulname>[,<Modulname>...]\n                  Begrenzt die gesamten beobachtbaren Module\n    --list-modules [<Modulname>[,<Modulname>...]]\n                  F\u00FChrt die beobachtbaren Module auf und beendet den Vorgang\n    --dry-run     Erstellt VM, f\u00FChrt jedoch die Hauptmethode nicht aus.\n                  Diese --dry-run-Option kann zur Validierung der Befehlszeilenoptionen\n                  n\u00FCtzlich sein, wie der Modulsystemkonfiguration.\n    -D<Name>=<Wert>\n                  Setzt eine Systemeigenschaft\n    -verbose:[class|gc|jni]\n                  Aktiviert Verbose-Ausgabe\n    -version      Druckt Produktversion und beendet den Vorgang\n    -showversion  Druckt Produktversion und f\u00E4hrt fort\n    -? -help --help\n                  Gibt diese Hilfemeldung aus\n    -X            Gibt Hilfe zu Nicht-Standardoptionen aus\n    -ea[:<Packagename>...|:<Klassenname>]\n    -enableassertions[:<Packagename>...|:<Klassenname>]\n                  Aktiviert Assertions mit angegebener Granularit\u00E4t\n    -da[:<Packagename>...|:<Klassenname>]\n    -disableassertions[:<Packagename>...|:<Klassenname>]\n                  Deaktiviert Assertions mit angegebener Granularit\u00E4t\n    -esa | -enablesystemassertions\n                  Aktiviert System-Assertions\n    -dsa | -disablesystemassertions\n                  Deaktiviert System-Assertions\n    -agentlib:<Lib-Name>[=<Optionen>]\n                  L\u00E4dt native Agent Library <Lib-Name>, Beispiel: -agentlib:jdwp\n                  siehe auch -agentlib:jdwp=help\n    -agentpath:<Pfadname>[=<Optionen>]\n                  L\u00E4dt native Agent Library nach vollst\u00E4ndigem Pfadnamen\n    -javaagent:<JAR-Pfad>[=<Optionen>]\n                  L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n    -splash:<Bildpfad>\n                  Zeigt Begr\u00FC\u00DFungsbildschirm mit angegebenem Bild an\n                  HiDPI-skalierte Bilder werden automatisch unterst\u00FCtzt und verwendet,\n                  sofern verf\u00FCgbar. Der nicht skalierte Bilddateiname, z.B. image.ext,\n                  muss immer als Argument an die Option -splash \u00FCbergeben werden.\n                  Das geeignetste skalierte Bild wird automatisch\n                  ausgew\u00E4hlt.\n                  Weitere Informationen finden Sie in der Dokumentation zu SplashScreen-API.\n    @<Dateipfad>   Liest Optionen aus der angegebenen Datei\nZur Angabe eines Arguments f\u00FCr eine lange Option k\u00F6nnen Sie --<Name>=<Wert> oder\n--<Name> <Wert> verwenden.\n
 See Weitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           Ausf\u00FChrung im gemischten Modus (Standard)\n    -Xint             Nur Ausf\u00FChrung im interpretierten Modus\n    -Xbootclasspath/a:<Verzeichnisse und ZIP-/JAR-Dateien durch {0} getrennt>\n                      H\u00E4ngt an das Ende des Bootstrap Classpath an\n    -Xdiag            Zeigt zus\u00E4tzliche Diagnosemeldungen an\n    -Xdiag:resolver   Zeigt Resolver-Diagnosemeldungen an\n    -Xnoclassgc       Deaktiviert Klassen-Garbage Collection\n    -Xincgc           Aktiviert inkrementelle Garbage Collection\n    -Xloggc:<file>    Protokolliert GC-Status in einer Datei mit Zeitstempeln\n    -Xbatch           Deaktiviert Hintergrundkompilierung\n    -Xms<size>        Legt anf\u00E4ngliche Java-Heap-Gr\u00F6\u00DFe fest\n    -Xmx<size>        Legt maximale Java-Heap-Gr\u00F6\u00DFe fest\n    -Xss<size>        Legt Java-Threadstackgr\u00F6\u00DFe fest\n    -Xprof            Gibt CPU-Profilingdaten aus\n    -Xfuture          Aktiviert strengste Pr\u00FCfungen, antizipiert zuk\u00FCnftigen Standardwert\n    -Xrs              Reduziert Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n    -Xcheck:jni       F\u00FChrt zus\u00E4tzliche Pr\u00FCfungen f\u00FCr JNI-Funktionen durch\n    -Xshare:off       Kein Versuch, gemeinsame Klassendaten zu verwenden\n    -Xshare:auto      Verwendet gemeinsame Klassendaten, wenn m\u00F6glich (Standard)\n    -Xshare:on        Erfordert die Verwendung gemeinsamer Klassendaten, sonst verl\u00E4uft der Vorgang nicht erfolgreich.\n    -XshowSettings    Zeigt alle Einstellungen an und f\u00E4hrt fort\n    -XshowSettings:all\n                      Zeigt alle Einstellungen an und f\u00E4hrt fort\n    -XshowSettings:vm Zeigt alle VM-bezogenen Einstellungen an und f\u00E4hrt fort\n    -XshowSettings:properties\n                      Zeigt alle Eigenschaftseinstellungen an und f\u00E4hrt fort\n    -XshowSettings:locale\n                      Zeigt alle gebietsschemabezogenen Einstellungen an und f\u00E4hrt fort\n    -XaddReads:<module>=<other-module>(,<other-module>)*\n                      <module> liest andere Module\n                      unabh\u00E4ngig von der Moduldeklaration\n    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      <module> exportiert <package> in andere Module\n                      unabh\u00E4ngig von der Moduldeklaration\n    -Xpatch:<module>=<file>({0}<file>)*\n                      Modul mit Klassen und Ressourcen in JAR-Dateien oder Verzeichnissen\n                      au\u00DFer Kraft setzen oder erg\u00E4nzen\n    -Xdisable-@files  Deaktiviert weitere Argumentdateierweiterung\n\nDie -X-Optionen sind keine Standardoptionen und k\u00F6nnen ohne Vorank\u00FCndigung ge\u00E4ndert werden.\n
+java.launcher.X.usage=\    -Xbatch           Deaktiviert Hintergrundkompilierung\n    -Xbootclasspath/a:<Verzeichnisse und ZIP-/JAR-Dateien durch {0} getrennt>\n                      an Ende von Bootstrap-Klassenpfad anh\u00E4ngen\n    -Xcheck:jni       F\u00FChrt zus\u00E4tzliche Pr\u00FCfungen f\u00FCr JNI-Funktionen aus\n    -Xcomp            Erzwingt Kompilierung von Methoden beim ersten Aufruf\n    -Xdebug           Wird zur Abw\u00E4rtskompatiblit\u00E4t bereitgestellt\n    -Xdiag            Zeigt zus\u00E4tzliche Diagnosemeldungen\n    -Xdiag:resolver   Zeigt Resolver-Diagnosemeldungen\n    -Xdisable-@files  Deaktiviert das weitere Einblenden der Argumentdatei\n    -Xfuture          Aktiviert strengste Pr\u00FCfungen, als m\u00F6glicher zuk\u00FCnftiger Standardwert erwartet\n    -Xint             Nur Ausf\u00FChrung im interpretierten Modus\n    -Xinternalversion\n                      Zeigt detailliertere JVM-Versionsinformationen an als die\n                      -version-Option\n    -Xloggc:<file>    Protokolliert GC-Status in einer Datei mit Zeitstempeln\n    -Xmixed           Ausf\u00FChrung im gemischten Modus (Standard)\n    -Xmn<size>        Setzt die anf\u00E4ngliche und maximale Gr\u00F6\u00DFe (in Byte) des Heaps\n                      f\u00FCr die junge Generation (Nursery)\n    -Xms<size>        Setzt die anf\u00E4ngliche Java-Heap-Gr\u00F6\u00DFe\n    -Xmx<size>        Setzt die maximale Java-Heap-Gr\u00F6\u00DFe\n    -Xnoclassgc       Deaktiviert die Klassen-Garbage Collection\n    -Xprof            Gibt CPU-Profilierungsdaten aus\n    -Xrs              Reduziert die Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n    -Xshare:auto      Verwendet freigegebene Klassendaten, wenn m\u00F6glich (Standard)\n    -Xshare:off       Versucht nicht, freigegebene Klassendaten zu verwenden\n    -Xshare:on        Erfordert die Verwendung von freigegebenen Klassendaten, verl\u00E4uft sonst nicht erfolgreich.\n    -XshowSettings    Zeigt alle Einstellungen und f\u00E4hrt fort\n    -XshowSettings:all\n                      Zeigt alle Einstellungen und f\u00E4hrt fort\n    -XshowSettings:locale\n                      Zeigt alle gebietsschemabezogenen Einstellungen und f\u00E4hrt fort\n    -XshowSettings:properties\n                      Zeigt alle Eigenschaftseinstellungen und f\u00E4hrt fort\n    -XshowSettings:vm Zeigt alle VM-bezogenen Einstellungen und f\u00E4hrt fort\n    -Xss<size>        Setzt Stackgr\u00F6\u00DFe des Java-Threads\n    -Xverify          Setzt den Modus der Bytecodeverifizierung\n    --add-reads <Modul>=<Zielmodul>(,<Zielmodul>)*\n                      Aktualisiert <Modul>, damit <Zielmodul> gelesen wird, ungeachtet \n                      der Moduldeklaration. \n                      <Zielmodul> kann ALL-UNNAMED sein, um alle unbenannten\n                      Module zu lesen.\n    --add-exports <Modul>/<Package>=<Zielmodul>(,<Zielmodul>)*\n                      Aktualisiert <Modul>, um <Package> in <Zielmodul> zu exportieren,\n                      ungeachtet der Moduldeklaration.\n                      <Zielmodul> kann ALL-UNNAMED sein, um in alle \n                      unbenannten Module zu exportieren.\n    --patch-module <Modul>=<Datei>({0}<Datei>)*\n                      Setzt ein Modul au\u00DFer Kraft oder erweitert ein Modul mit Klassen und Ressourcen\n                      in JAR-Dateien oder -Verzeichnissen.\n\nDiese Optionen sind Nicht-Standardoptionen und k\u00F6nnen ohne Ank\u00FCndigung ge\u00E4ndert werden.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\nDie folgenden Optionen sind f\u00FCr Mac OS X spezifisch:\n    -XstartOnFirstThread\n                      main()-Methode f\u00FCr den ersten (AppKit) Thread ausf\u00FChren\n    -Xdock:name=<application name>\n                      Den im Dock angezeigten Standardanwendungsnamen \u00FCberschreiben\n    -Xdock:icon=<Pfad zu Symboldatei>\n                      Das im Dock angezeigte Standardsymbol \u00FCberschreiben\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_es.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_es.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   Sintaxis: {0} [opciones] class [args...]\n           (para ejecutar una clase)\n   o  {0} [opciones] -jar jarfile [args...]\n           (para ejecutar un archivo jar)\n   o  {0} [opciones] -mp <ruta_m\u00F3dulo> -m <nombre_m\u00F3dulo>[/<clase_principal>] [args...]\n           (para ejecutar una clase principal en un m\u00F3dulo)\ndonde las opciones incluyen:\n
+java.launcher.opt.header  =   Sintaxis: {0} [opciones] class [argumentos...]\n           (para ejecutar una clase)\n   o  {0} [opciones] -jar jarfile [argumentos...]\n           (para ejecutar un archivo jar)\n   o  {0} [opciones] -p <ruta_m\u00F3dulo> -m <nombre_m\u00F3dulo>[/<clase_principal>] [argumentos...]\n           (para ejecutar la clase principal en un m\u00F3dulo)\ndonde las opciones incluyen:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  usar un modelo de datos de {0} bits, si est\u00E1 disponible\n
+java.launcher.opt.datamodel  =\    -d{0}\t  Anticuada, se eliminar\u00E1 en una versi\u00F3n futura\n
 java.launcher.opt.vmselect   =\    {0}\t  para seleccionar la VM "{1}"\n
 java.launcher.opt.hotspot    =\    {0}\t  es un sin\u00F3nimo de la VM "{1}" [anticuada]\n
 
@@ -34,11 +34,12 @@
 java.launcher.ergo.message2  =\                  porque la ejecuci\u00F3n se est\u00E1 llevando a cabo en una m\u00E1quina de clase de servidor.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <ruta de acceso de b\u00FAsqueda de clases de los directorios y archivos zip/jar>\n    -classpath <ruta de acceso de b\u00FAsqueda de clases de los directorios y archivos zip/jar>\n                  Lista separada por {0} de directorios, archivos JAR\n                  y archivos ZIP para buscar archivos de clase.\n    -mp <ruta_m\u00F3dulo>\n    -modulepath <ruta_m\u00F3dulo>...\n                  Lista separada por {0} de directorios, cada directorio\n                  es un directorio de m\u00F3dulos.\n    -upgrademodulepath <ruta_m\u00F3dulo>...\n                  Lista separada por {0} de directorios, cada directorio\n                  es un directorio de m\u00F3dulos que sustituye a los m\u00F3dulos\n                  actualizables en la imagen de tiempo de ejecuci\u00F3n\n    -m <nombre_m\u00F3dulo>[/<clase_principal>]\n                  m\u00F3dulo inicial que resolver y nombre de la clase principal\n                  que ejecutar si el m\u00F3dulo no la especifica\n    -addmods <nombre_m\u00F3dulo>[,<nombre_modulo>...]\n                  m\u00F3dulos ra\u00EDz que resolver, adem\u00E1s del m\u00F3dulo inicial\n    -limitmods <nombre_m\u00F3dulo>[,<nombre_m\u00F3dulo>...]\n                  limitar el universo de los m\u00F3dulos observables\n    -listmods[:<nombre_m\u00F3dulo>[,<nombre_m\u00F3dulo>...]]\n                  mostrar los m\u00F3dulos observables y salir\n    --dry-run     crear VM pero no ejecutar m\u00E9todo principal.\n                  Esta opci\u00F3n --dry-run puede ser \u00FAtil para validar las\n                  opciones de l\u00EDnea de comandos como la configuraci\u00F3n del sistema de m\u00F3dulo.\n    -D<nombre>=<valor>\n                  definir una propiedad del sistema\n    -verbose:[class|gc|jni]\n                  activar la salida detallada\n    -version      imprimir la versi\u00F3n del producto y salir\n    -showversion  imprimir la versi\u00F3n del producto y continuar\n    -? -help      imprimir este mensaje de ayuda\n    -X            imprimir la ayuda de opciones no est\u00E1ndar\n    -ea[:<nombre_paquete>...|:<nombre_clase>]\n    -enableassertions[:<nombre_paquete>...|:<nombre_clase>]\n                  activar afirmaciones con la granularidad especificada\n    -da[:<nombre_paquete>...|:<nombre_clase>]\n    -disableassertions[:<nombre_paquete>...|:<nombre_clase>]\n                  desactivar afirmaciones con la granularidad especificada\n    -esa | -enablesystemassertions\n                  activar afirmaciones del sistema\n    -dsa | -disablesystemassertions\n                  desactivar afirmaciones del sistema\n    -agentlib:<nombre_bib>[=<opciones>]\n                  cargar biblioteca de agentes nativos <nombre_bib>, por ejemplo, -agentlib:jdwp\n                  ver tambi\u00E9n -agentlib:jdwp=help\n    -agentpath:<nombre_ruta>[=<opciones>]\n                  cargar biblioteca de agentes nativos por ruta completa\n    -javaagent:<ruta_jar>[=<opciones>]\n                  cargar agente de lenguaje de programaci\u00F3n Java, ver java.lang.instrument\n    -splash:<ruta_imagen>\n                  mostrar pantalla de bienvenida con la imagen especificada\n    @<ruta_archivo>   leer opciones del archivo especificado\n
+java.launcher.opt.footer     =\    -cp <ruta de b\u00FAsqueda de clases de los directorios y archivos zip/jar>\n    -classpath <ruta de b\u00FAsqueda de clases de los directorios y archivos zip/jar>\n    --class-path <ruta de b\u00FAsqueda de clases de los directorios y archivos zip/jar>\n                  Lista separada por {0} de directorios, archivos JAR\n                  y archivos ZIP para buscar archivos de clase.\n    -p <ruta_m\u00F3dulo>\n    --module-path <ruta_m\u00F3dulo>...\n                  Lista separada por {0} de directorios, cada directorio\n                  es un directorio de m\u00F3dulos.\n    --upgrade-module-path <ruta_m\u00F3dulo>...\n                  Lista separada por {0} de directorios, cada directorio\n                  es un directorio de m\u00F3dulos que sustituye a los m\u00F3dulos\n                  actualizables en la imagen de tiempo de ejecuci\u00F3n\n    -m <m\u00F3dulo>[/<clase_principal>]\n    --module <nombre_m\u00F3dulo>[/<clase_principal>]\n                  m\u00F3dulo inicial que resolver y nombre de la clase principal\n                  que ejecutar si el m\u00F3dulo no la especifica\n    --add-modules <nombre_m\u00F3dulo>[,<nombre_m\u00F3dulo>...]\n                  m\u00F3dulos ra\u00EDz que resolver, adem\u00E1s del m\u00F3dulo inicial.\n                  <nombre_m\u00F3dulo> tambi\u00E9n puede ser ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH.\n    --limit-modules <nombre_m\u00F3dulo>[,<nombre_m\u00F3dulo>...]\n                  limitar el universo de los m\u00F3dulos observables\n    --list-modules [<nombre_m\u00F3dulo>[,<nombre_m\u00F3dulo>...]]\n                  mostrar los m\u00F3dulos observables y salir\n    --dry-run     crear VM pero no ejecutar m\u00E9todo principal.\n                  Esta opci\u00F3n --dry-run puede ser \u00FAtil para validar las\n                  opciones de l\u00EDnea de comandos como la configuraci\u00F3n del sistema de m\u00F3dulo.\n    -D<nombre>=<valor>\n                  definir una propiedad del sistema\n    -verbose:[class|gc|jni]\n                  activar la salida detallada\n    -version      imprimir la versi\u00F3n del producto y salir\n    -showversion  imprimir la versi\u00F3n del producto y continuar\n    -? -help --help\n                  imprimir este mensaje de ayuda\n    -X            imprimir la ayuda de opciones no est\u00E1ndar\n    -ea[:<nombre_paquete>...|:<nombre_clase>]\n    -enableassertions[:<nombre_paquete>...|:<nombre_clase>]\n                  activar afirmaciones con la granularidad especificada\n    -da[:<nombre_paquete>...|:<nombre_clase>]\n    -disableassertions[:<nombre_paquete>...|:<nombre_clase>]\n                  desactivar afirmaciones con la granularidad especificada\n    -esa | -enablesystemassertions\n                  activar afirmaciones del sistema\n    -dsa | -disablesystemassertions\n                  desactivar afirmaciones del sistema\n    -agentlib:<nombre_bib>[=<opciones>]\n                  cargar biblioteca de agentes nativos <nombre_bib>, por ejemplo, -agentlib:jdwp\n                  ver tambi\u00E9n -agentlib:jdwp=help\n    -agentpath:<nombre_ruta>[=<opciones>]\n                  cargar biblioteca de agentes nativos por nombre de ruta completo\n    -javaagent:<ruta_jar>[=<opciones>]\n                  cargar agente de lenguaje de programaci\u00F3n Java, ver java.lang.instrument\n    -splash:<ruta_imagen>\n                  mostrar pantalla de bienvenida con la imagen especificada\n                  Las im\u00E1genes a escala HiDPI est\u00E1n soportadas y se usan autom\u00E1ticamente\n                  si est\u00E1n disponibles. El nombre de archivo de la imagen sin escala, por ejemplo, image.ext,\n                  siempre debe transferirse como el argumento en la opci\u00F3n -splash.\n                  La imagen a escala m\u00E1s adecuada que se haya proporcionado se escoger\u00E1\n                  autom\u00E1ticamente.\n                  Consulte la documentaci\u00F3n de \
+la API de la pantalla de bienvenida para obtener m\u00E1s informaci\u00F3n.\n    en<ruta_archivo>   leer opciones del archivo especificado\nPara especificar un argumento para una opci\u00F3n larga, puede usar --<nombre>=<valor> o\n--<nombre> <valor>.\n
 See http://www.oracle.com/technetwork/java/javase/documentation/index.html para obtener m\u00E1s informaci\u00F3n.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           ejecuci\u00F3n de modo mixto (por defecto)\n    -Xint             solo ejecuci\u00F3n de modo interpretado\n    -Xbootclasspath/a:<directorios y archivos zip/jar separados por {0}>\n                       agregar al final de la ruta de acceso de la clase de inicializaci\u00F3n de datos\n    -Xdiag             mostrar mensajes de diagn\u00F3stico adicionales\n    -Xdiag:resolver   mostrar mensajes de diagn\u00F3stico de resoluci\u00F3n\n    -Xnoclassgc        desactivar la recolecci\u00F3n de basura de clases\n    -Xloggc:<archivo>     registrar el estado de GC en un archivo con registros de hora\n    -Xbatch           desactivar compilaci\u00F3n en segundo plano\n    -Xms<tama\u00F1o>        definir tama\u00F1o de pila Java inicial\n    -Xmx<tama\u00F1o>        definir tama\u00F1o de pila Java m\u00E1ximo\n    -Xss<tama\u00F1o>        definir tama\u00F1o de la pila del thread de Java\n    -Xprof            datos de salida de creaci\u00F3n de perfil de CPU\n    -Xfuture          activar las comprobaciones m\u00E1s estrictas, anticip\u00E1ndose al futuro valor por defecto\n    -Xrs              reducir el uso de se\u00F1ales de sistema operativo por parte de Java/VM (consulte la documentaci\u00F3n)\n    -Xcheck:jni       realizar comprobaciones adicionales para las funciones de JNI\n    -Xshare:off       no intentar usar datos de clase compartidos\n    -Xshare:auto      usar datos de clase compartidos si es posible (valor por defecto)\n    -Xshare:on         es obligatorio el uso de datos de clase compartidos, de lo contrario se emitir\u00E1 un fallo.\n    -XshowSettings    show all settings and continue\n    -XshowSettings:all\n                      mostrar todos los valores y continuar\n    -XshowSettings:vm show all vm related settings and continue\n    -XshowSettings:properties\n                      mostrar todos los valores y continuar\n    -XshowSettings:locale\n                       mostrar todos los valores relacionados con la configuraci\u00F3n regional y continuar\n    -XaddReads:<m\u00F3dulo>=<otro_m\u00F3dulo>(,<otro_m\u00F3dulo>)*\n                      <module> lee otros m\u00F3dulos,\n                      independientemente de la declaraci\u00F3n del m\u00F3dulo\n    -XaddExports:<m\u00F3dulo>/<paquete>=<otro_m\u00F3dulo>(,<otro_m\u00F3dulo>)*\n                      <m\u00F3dulo> exporta <paquete> a otros m\u00F3dulos,\n                      independientemente de la declaraci\u00F3n del m\u00F3dulo\n    -Xpatch:<m\u00F3dulo>=<archivo>({0}<archivo>)*\n                      Anular o aumentar un m\u00F3dulo con clases y recursos\n                      en directorios o archivos JAR\n    -Xdisable-@files  desactivar la ampliaci\u00F3n de archivos de argumentos\n\nLas opciones -X no son est\u00E1ndar y est\u00E1n sujetas a cambios sin previo aviso.\n
+java.launcher.X.usage=\    -Xbatch           desactivar compilaci\u00F3n de fondo\n    -Xbootclasspath/a:<directorios y archivos zip/jar separados por {0}>\n                      agregar al final de la ruta de la clase de inicializaci\u00F3n de datos\n    -Xcheck:jni       realizar comprobaciones adicionales para las funciones de JNI\n    -Xcomp            fuerza la compilaci\u00F3n de m\u00E9todos en la primera llamada\n    -Xdebug           se proporciona para ofrecer compatibilidad con versiones anteriores\n    -Xdiag            mostrar mensajes de diagn\u00F3stico adicionales\n    -Xdiag:resolver   mostrar mensajes de diagn\u00F3stico de resoluci\u00F3n\n    -Xdisable-@files  desactivar la ampliaci\u00F3n de archivos de m\u00E1s argumentos\n    -Xfuture          activar las comprobaciones m\u00E1s estrictas, anticip\u00E1ndose al futuro valor por defecto\n    -Xint             solo ejecuci\u00F3n de modo interpretado\n    -Xinternalversion\n                      muestra una informaci\u00F3n de la versi\u00F3n de JVM m\u00E1s detallada que la\n                      opci\u00F3n -version\n    -Xloggc:<archivo>    registrar el estado de GC en un archivo con registros de hora\n    -Xmixed           ejecuci\u00F3n de modo mixto (por defecto)\n    -Xmn<tama\u00F1o>        define el tama\u00F1o inicial y m\u00E1ximo (en bytes) de la pila\n                      para la generaci\u00F3n m\u00E1s joven (espacio infantil)\n    -Xms<size>        define el tama\u00F1o inicial de la pila de Java\n    -Xmx<size>        define el tama\u00F1o m\u00E1ximo de la pila de Java\n    -Xnoclassgc       desactivar la recolecci\u00F3n de basura de clases\n    -Xprof            datos de creaci\u00F3n de perfiles de CPU de salida\n    -Xrs              reducir el uso de se\u00F1ales de sistema operativo por parte de Java/VM (consulte la documentaci\u00F3n)\n    -Xshare:auto      usar datos de clase compartidos si es posible (valor por defecto)\n    -Xshare:off       no intentar usar datos de clase compartidos\n    -Xshare:on        es obligatorio el uso de datos de clase compartidos, de lo contrario se producir\u00E1 un fallo.\n    -XshowSettings    mostrar toda la configuraci\u00F3n y continuar\n    -XshowSettings:all\n                      mostrar todos los valores y continuar\n    -XshowSettings:locale\n                      mostrar todos los valores relacionados con la configuraci\u00F3n regional y continuar\n    -XshowSettings:properties\n                      mostrar todos los valores de propiedad y continuar\n    -XshowSettings:vm mostrar todos los valores relacionados con vm y continuar\n    -Xss<tama\u00F1o>        definir tama\u00F1o de la pila del thread de Java\n    -Xverify          define el modo del verificador de c\u00F3digo de bytes\n    --add-reads <m\u00F3dulo>=<m\u00F3dulo-destino>(,<m\u00F3dulo-destino>)*\n                      actualiza <m\u00F3dulo> para leer <m\u00F3dulo-destino>, independientemente\n                      de la declaraci\u00F3n del m\u00F3dulo. \n                      <m\u00F3dulo-destino> puede ser ALL-UNNAMED para leer todos los\n                      m\u00F3dulos sin nombre.\n    --add-exports <m\u00F3dulo>/<paquete>=<m\u00F3dulo-destino>(,<m\u00F3dulo-destino>)*\n                      actualiza <m\u00F3dulo> para exportar <paquete> en <m\u00F3dulo-destino>,\n                      independientemente de la declaraci\u00F3n del m\u00F3dulo.\n                      <m\u00F3dulo-destino> puede ser ALL-UNNAMED para exportar a todos los\n                      m\u00F3dulos sin nombre.\n    --patch-module <m\u00F3dulo>=<archivo>({0}<archivo>)*\n                      Aumentar o anular un m\u00F3dulo con clases y recursos\n                      en directorios y archivos JAR\n\nEstas opciones no son est\u00E1ndar y est\u00E1n sujetas a cambio sin previo aviso.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\nLas siguientes opciones son espec\u00EDficas para Mac OS X:\n    -XstartOnFirstThread\n                      ejecutar el m\u00E9todo main() del primer thread (AppKit)\n    -Xdock:name=<application name>\n                      sustituir al nombre por defecto de la aplicaci\u00F3n que se muestra en el Dock\n    -Xdock:icon=<ruta de acceso a archivo de icono>\n                      sustituir al icono por defecto que se muestra en el Dock\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_fr.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_fr.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   Syntaxe : {0} [options] class [args...]\n           (pour l''ex\u00E9cution d''une classe)\n   ou  {0} [options] -jar jarfile [args...]\n           (pour l''ex\u00E9cution d''un fichier JAR)\n   ou  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (pour l''ex\u00E9cution de la classe principale dans un module)\no\u00F9 options comprend les \u00E9l\u00E9ments suivants :\n
+java.launcher.opt.header  =   Syntaxe : {0} [options] class [args...]\n           (pour l''ex\u00E9cution d''une classe)\n   ou  {0} [options] -jar jarfile [args...]\n           (pour l''ex\u00E9cution d''un fichier JAR)\n   ou  {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (pour l''ex\u00E9cution de la classe principale dans un module)\no\u00F9 options comprend les \u00E9l\u00E9ments suivants :\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  utilisez le mod\u00E8le de donn\u00E9es {0} bits s''il est disponible\n
+java.launcher.opt.datamodel  =\    -d{0}\t  En phase d''abandon, sera enlev\u00E9 dans une version future\n
 java.launcher.opt.vmselect   =\    {0}\t  pour s\u00E9lectionner la machine virtuelle "{1}"\n
 java.launcher.opt.hotspot    =\    {0}\t  est un synonyme pour la machine virtuelle "{1}"  [en phase d''abandon]\n
 
@@ -34,11 +34,13 @@
 java.launcher.ergo.message2  =\                  car vous ex\u00E9cutez une machine de classe de serveur.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <chemin de recherche de classe de r\u00E9pertoires et de fichiers ZIP/JAR>\n    -classpath <chemin de recherche de classe de r\u00E9pertoires et de fichiers ZIP/JAR>\n                  Liste de r\u00E9pertoires, d''archives JAR\n                  et d''archives ZIP s\u00E9par\u00E9s par des {0} dans laquelle rechercher les fichiers de classe.\n    -mp <chemin de module>\n    -modulepath <chemin de module>...\n                  Liste de r\u00E9pertoires s\u00E9par\u00E9s par des {0}, chaque r\u00E9pertoire\n                  est un r\u00E9pertoire de modules.\n    -upgrademodulepath <chemin de module>...\n                  Liste de r\u00E9pertoires s\u00E9par\u00E9s par des {0}, chaque r\u00E9pertoire\n                  est un r\u00E9pertoire de modules qui remplace des modules\n                  pouvant \u00EAtre mis \u00E0 niveau dans l''image d''ex\u00E9cution\n    -m <modulename>[/<mainclass>]\n                  module initial \u00E0 r\u00E9soudre et nom de la classe principale\n                  \u00E0 ex\u00E9cuter si elle n''est pas indiqu\u00E9e par le module\n    -addmods <modulename>[,<modulename>...]\n                  modules racine \u00E0 r\u00E9soudre en plus du module initial\n    -limitmods <modulename>[,<modulename>...]\n                  limitation de l''univers de modules observables\n    -listmods[:<modulename>[,<modulename>...]]\n                  \u00E9num\u00E9ration des modules observables et fin de l''op\u00E9ration\n    --dry-run     cr\u00E9e une machine virtuelle mais n''ex\u00E9cute pas la m\u00E9thode principale.\n                  Cette option --dry-run peut s''av\u00E9rer utile pour la validation des\n                  options de ligne de commandes telles que la configuration syst\u00E8me de module.\n    -D<nom>=<valeur>\n                  d\u00E9finition d''une propri\u00E9t\u00E9 syst\u00E8me\n    -verbose:[class|gc|jni]\n                  activation de la sortie en mode verbose\n    -version      affichage de la version du produit et fin de l''op\u00E9ration\n    -showversion  affichage de la version du produit et poursuite de l''op\u00E9ration\n    -? -help      affichage du message d''aide\n    -X            affichage de l''aide sur les options non standard\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  activation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  d\u00E9sactivation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n    -esa | -enablesystemassertions\n                  activation des assertions syst\u00E8me\n    -dsa | -disablesystemassertions\n                  d\u00E9sactivation des assertions syst\u00E8me\n    -agentlib:<libname>[=<options>]\n                  chargement de la biblioth\u00E8que d''agent natif <libname>, par exemple : -agentlib:jdwp\n                  voir aussi -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  chargement de la biblioth\u00E8que d''agent natif via le chemin d''acc\u00E8s complet\n    -javaagent:<jarpath>[=<options>]\n                  chargement de l''agent du langage de programmation Java, voir java.lang.instrument\n    -splash:<imagepath>\n                  affichage de l''\u00E9cran d''accueil avec l''image indiqu\u00E9e\n    @<filepath>   lire les options \u00E0 partir du fichier indiqu\u00E9\n
+java.launcher.opt.footer     =\    -cp <chemin de recherche de classe de r\u00E9pertoires et de fichiers ZIP/JAR>\n    -classpath <chemin de recherche de classe de r\u00E9pertoires et de fichiers ZIP/JAR>\n    --class-path <chemin de recherche de classe de r\u00E9pertoires et de fichiers ZIP/JAR>\n                  Liste de r\u00E9pertoires, d''archives JAR\n                  et d''archives ZIP s\u00E9par\u00E9s par des {0} dans laquelle rechercher les fichiers de classe.\n    -p <chemin de module>\n    --module-path <chemin de module>...\n                  Liste de r\u00E9pertoires s\u00E9par\u00E9s par des {0}, chaque r\u00E9pertoire\n                  est un r\u00E9pertoire de modules.\n    --upgrade-module-path <chemin de module>...\n                  Liste de r\u00E9pertoires s\u00E9par\u00E9s par des {0}, chaque r\u00E9pertoire\n                  est un r\u00E9pertoire de modules qui remplace des modules\n                  pouvant \u00EAtre mis \u00E0 niveau dans l''image d''ex\u00E9cution\n    -m <module>[/<mainclass>]\n    --module <modulename>[/<mainclass>]\n                  module initial \u00E0 r\u00E9soudre et nom de la classe principale\n                  \u00E0 ex\u00E9cuter si elle n''est pas indiqu\u00E9e par le module\n    --add-modules <modulename>[,<modulename>...]\n                  modules racine \u00E0 r\u00E9soudre en plus du module initial.\n                  <modulename> peut \u00E9galement \u00EAtre ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH.\n    --limit-modules <modulename>[,<modulename>...]\n                  limitation de l''univers de modules observables\n    --list-modules [<modulename>[,<modulename>...]]\n                  \u00E9num\u00E9ration des modules observables et fin de l''op\u00E9ration\n    --dry-run     cr\u00E9e une machine virtuelle mais n''ex\u00E9cute pas la m\u00E9thode principale.\n                  Cette option --dry-run peut s''av\u00E9rer utile pour la validation des\n                  options de ligne de commandes telles que la configuration syst\u00E8me de module.\n    -D<nom>=<valeur>\n                  d\u00E9finition d''une propri\u00E9t\u00E9 syst\u00E8me\n    -verbose:[class|gc|jni]\n                  activation de la sortie en mode verbose\n    -version      affichage de la version du produit et fin de l''op\u00E9ration\n    -showversion  affichage de la version du produit et poursuite de l''op\u00E9ration\n    -? -help --help\n                  affichage du message d''aide\n    -X            affichage de l''aide sur les options non standard\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  activation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  d\u00E9sactivation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n    -esa | -enablesystemassertions\n                  activation des assertions syst\u00E8me\n    -dsa | -disablesystemassertions\n                  d\u00E9sactivation des assertions syst\u00E8me\n    -agentlib:<libname>[=<options>]\n                  chargement de la biblioth\u00E8que d''agent natif <libname>, par exemple : -agentlib:jdwp\n                  voir aussi -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  chargement de la biblioth\u00E8que d''agent natif via le chemin d''acc\u00E8s complet\n    -javaagent:<jarpath>[=<options>]\n                  chargement de l''agent du langage de programmation Java, voir java.lang.instrument\n    -splash:<imagepath>\n                  affichage de l''\u00E9cran d''accueil avec l''image indiqu\u00E9e\n                  Les images redimensionn\u00E9es HiDPI sont automatiquement prises en charge et utilis\u00E9es\n                  si elles sont disponibles. Le nom de fichier d''une image non redimensionn\u00E9e, par ex. image.ext,\n                  doit toujours \
+\u00EAtre transmis comme argument \u00E0 l''option -splash.\n                  L''image redimensionn\u00E9e fournie la plus appropri\u00E9e sera automatiquement\n                  s\u00E9lectionn\u00E9e.\n                  Pour plus d''informations, reportez-vous \u00E0 la documentation relative \u00E0 l''API SplashScreen.\n    @<filepath>   lire les options \u00E0 partir du fichier indiqu\u00E9\nPour indiquer un argument pour une option longue, vous pouvez utiliser --<name>=<value> ou\n--<name> <value>.\n
 See http://www.oracle.com/technetwork/java/javase/documentation/index.html pour plus de d\u00E9tails.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           ex\u00E9cution en mode mixte (valeur par d\u00E9faut)\n    -Xint             ex\u00E9cution en mode interpr\u00E9t\u00E9 uniquement\n    -Xbootclasspath/a:<r\u00E9pertoires et fichiers ZIP/JAR s\u00E9par\u00E9s par des {0}>\n                      ajout \u00E0 la fin du chemin de classe bootstrap\n    -Xdiag            affichage de messages de diagnostic suppl\u00E9mentaires\n    -Xdiag:resolver   affichage de messages de diagnostic du r\u00E9solveur\n    -Xnoclassgc       d\u00E9sactivation du nettoyage de la m\u00E9moire de la classe\n    -Xloggc:<file>    journalisation du statut de nettoyage de la m\u00E9moire dans un fichier avec horodatage\n    -Xbatch           d\u00E9sactivation de la compilation en arri\u00E8re-plan\n    -Xms<size>        d\u00E9finition de la taille initiale des portions de m\u00E9moire Java\n    -Xmx<size>        d\u00E9finition de la taille maximale des portions de m\u00E9moire Java\n    -Xss<size>        d\u00E9finition de la taille de pile de threads Java\n    -Xprof            sortie des donn\u00E9es de profilage d''UC\n    -Xfuture          activation des contr\u00F4les les plus stricts en vue d''anticiper la future valeur par d\u00E9faut\n    -Xrs              r\u00E9duction de l''utilisation des signaux d''OS par Java/la machine virtuelle (voir documentation)\n    -Xcheck:jni       ex\u00E9cution de contr\u00F4les suppl\u00E9mentaires pour les fonctions JNI\n    -Xshare:off       aucune tentative d''utilisation des donn\u00E9es de classe partag\u00E9e\n    -Xshare:auto      utilisation des donn\u00E9es de classe partag\u00E9e si possible (valeur par d\u00E9faut)\n    -Xshare:on        utilisation des donn\u00E9es de classe partag\u00E9e obligatoire ou \u00E9chec de l''op\u00E9ration\n    -XshowSettings    affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n    -XshowSettings:all\n                      affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n    -XshowSettings:vm affichage de tous les param\u00E8tres de machine virtuelle et poursuite de l''op\u00E9ration\n    -XshowSettings:properties\n                      affichage de tous les param\u00E8tres de propri\u00E9t\u00E9 et poursuite de l''op\u00E9ration\n    -XshowSettings:locale\n                      affichage de tous les param\u00E8tres d''environnement local et poursuite de l''op\u00E9ration\n    -XaddReads:<module>=<other-module>(,<other-module>)*\n                      <module> lecture de tous les modules,\n                      quelle que soit la d\u00E9claration de module\n    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      <module> exporte <package> vers d''autres modules,\n                      quelle que soit la d\u00E9claration de module\n    -Xpatch:<module>=<file>({0}<file>)*\n                      Remplacement ou augmentation d''un module avec des classes et des ressources\n                      dans des fichiers ou r\u00E9pertoires JAR\n    -Xdisable-@files  d\u00E9sactivation d''autres d\u00E9veloppements de fichier d''argument\n\nLes options -X ne sont pas standard et sont susceptibles de modification sans pr\u00E9avis.\n
+java.launcher.X.usage=\    -Xbatch           d\u00E9sactivation de la compilation en arri\u00E8re-plan\n    -Xbootclasspath/a:<r\u00E9pertoires et fichiers ZIP/JAR s\u00E9par\u00E9s par des {0}>\n                      ajout \u00E0 la fin du chemin de classe bootstrap\n    -Xcheck:jni        ex\u00E9cution de contr\u00F4les suppl\u00E9mentaires pour les fonctions JNI\n    -Xcomp            force la compilation de m\u00E9thodes au premier appel\n    -Xdebug           fourni pour la compatibilit\u00E9 amont\n    -Xdiag            affichage de messages de diagnostic suppl\u00E9mentaires\n    -Xdiag:resolver   affichage de messages de diagnostic du r\u00E9solveur\n    -Xdisable-@files  d\u00E9sactivation d''autres d\u00E9veloppements de fichier d''argument\n    -Xfuture           activation des contr\u00F4les les plus stricts en vue d''anticiper la future valeur par d\u00E9faut\n    -Xint             ex\u00E9cution en mode interpr\u00E9t\u00E9 uniquement\n    -Xinternalversion\n                      affiche des informations de version JVM plus d\u00E9taill\u00E9es que\n                      l''option -version\n    -Xloggc:<file>    journalisation du statut de l''op\u00E9ration de ramasse-miette dans un fichier avec horodatage\n    -Xmixed           ex\u00E9cution en mode mixte (valeur par d\u00E9faut)\n    -Xmn<size>        d\u00E9finit les tailles initiale et maximale (en octets) de la portion de m\u00E9moire\n                      pour la jeune g\u00E9n\u00E9ration (nursery)\n    -Xms<size>        d\u00E9finition de la taille initiale des portions de m\u00E9moire Java\n    -Xmx<size>        d\u00E9finition de la taille maximale des portions de m\u00E9moire Java\n    -Xnoclassgc       d\u00E9sactivation de l''op\u00E9ration de ramasse-miette de la classe\n    -Xprof            sortie des donn\u00E9es de profilage d''UC\n    -Xrs              r\u00E9duction de l''utilisation des signaux OS par Java/la machine virtuelle (voir documentation)\n    -Xshare:auto      utilisation des donn\u00E9es de classe partag\u00E9es si possible (valeur par d\u00E9faut)\n    -Xshare:off       aucune tentative d''utilisation des donn\u00E9es de classe partag\u00E9es\n    -Xshare:on        utilisation des donn\u00E9es de classe partag\u00E9es obligatoire ou \u00E9chec de l''op\u00E9ration\n    -XshowSettings    affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n    -XshowSettings:all\n                      affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n    -XshowSettings:locale\n                      affichage de tous les param\u00E8tres d''environnement local et poursuite de l''op\u00E9ration\n    -XshowSettings:properties\n                       affichage de tous les param\u00E8tres de propri\u00E9t\u00E9 et poursuite de l''op\u00E9ration\n    -XshowSettings:vm affichage de tous les param\u00E8tres de machine virtuelle et poursuite de l''op\u00E9ration\n    -Xss<size>        d\u00E9finition de la taille de pile de threads Java\n    -Xverify          d\u00E9finit le mode du v\u00E9rificateur de code ex\u00E9cutable\n    --add-reads <module>=<target-module>(,<target-module>)*\n                      met \u00E0 jour <module> pour lire <target-module>, sans tenir compte\n                      de la d\u00E9claration de module. \n                      <target-module> peut \u00EAtre ALL-UNNAMED pour lire tous les modules\n                      sans nom.\n    --add-exports <module>/<package>=<target-module>(,<target-module>)*\n                      met \u00E0 jour <module> pour exporter <package> vers <target-module>,\n                      sans tenir compte de la d\u00E9claration de module.\n                      <target-module> peut \u00EAtre ALL-UNNAMED pour effectuer un export vers tous\n                      les modules sans nom.\n    --patch-module <module>=<file>({0}<file>)*\n                      Remplacement ou augmentation d''un module avec des classes et des ressources\n                      dans des \
+fichiers ou des r\u00E9pertoires JAR.\n\nCes options ne sont pas standard et peuvent \u00EAtre modifi\u00E9es sans pr\u00E9avis.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\nLes options suivantes sont propres \u00E0 Mac OS X :\n    -XstartOnFirstThread\n                      ex\u00E9cute la m\u00E9thode main() sur le premier thread (AppKit)\n    -Xdock:name=<nom d'application>\n                      remplace le nom d'application par d\u00E9faut affich\u00E9 dans l'ancrage\n    -Xdock:icon=<chemin vers le fichier d'ic\u00F4ne>\n                      remplace l'ic\u00F4ne par d\u00E9faut affich\u00E9e dans l'ancrage\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_it.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_it.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   Uso: {0} [options] class [args...]\n           (per eseguire una classe)\n   oppure {0} [options] -jar jarfile [args...]\n           (per eseguire un file jar)\n   oppure {0} [options] -mp <percorsomodulo> -m <nomemodulo>[/<classeprincipale>] [args...]\n           (per eseguire la classe principale in un modulo)\nin cui options include:\n
+java.launcher.opt.header  =   Uso: {0} [opzioni] class [argomenti...]\n           (per eseguire una classe)\n   oppure {0} [opzioni] -jar jarfile [argomenti...]\n           (per eseguire un file jar)\n   oppure {0} [opzioni] -p <percorsomodulo> -m <nomemodulo>[/<classeprincipale>] [argomenti...]\n           (per eseguire la classe principale in un modulo)\ndove opzioni include:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  usare un modello di dati {0}-bit se disponibile\n
+java.launcher.opt.datamodel  =\    -d{0}\t  opzione non pi\u00F9 valida; verr\u00E0 rimossa in una release futura\n
 java.launcher.opt.vmselect   =\    {0}\t  per selezionare la VM "{1}"\n
 java.launcher.opt.hotspot    =\    {0}\t  \u00E8 un sinonimo per la VM "{1}" [non valido]\n
 
@@ -34,11 +34,12 @@
 java.launcher.ergo.message2  =\                  perch\u00E9 si utilizza un computer di classe server.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <classpath di ricerca di directory e file zip/jar>\n    -classpath <classpath di ricerca di directory e file zip/jar>\n                  Lista separata da {0} di directory e di archivi JAR\n                  e ZIP utilizzata per la ricerca di file di classe.\n    -mp <percorso modulo>\n    -modulepath <percorso modulo>...\n                  Lista separata da {0} di directory; ciascuna directory\n                  \u00E8 una directory di moduli.\n    -upgrademodulepath <percorso modulo>...\n                  Lista separata da {0} di directory; ciascuna directory\n                  \u00E8 una directory dei moduli che sostituiscono i moduli\n                  aggiornabili nell''immagine in fase di esecuzione.\n    -m <nome modulo>[/<classe principale>]\n                  Il modulo iniziale da risolvere e il nome della classe\n                  principale da eseguire se non specificata dal modulo.\n    -addmods <nome modulo>[,<nome modulo>...]\n                  Moduli root da risolvere in aggiunta al modulo iniziale.\n    -limitmods <nome modulo>[,<nome modulo>...]\n                  Limita l''universe dei moduli osservabili.\n    -listmods[:<nome modulo>[,<nome modulo>...]]\n                  Elenca i moduli osservabili ed esce.\n    --dry-run     Crea la VM ma non esegue il metodo principale.\n                  Pu\u00F2 essere utile, ad esempio, per la convalida delle opzioni della\n                  riga di comando utilizzate per la configurazione del sistema di moduli.\n    -D<nome>=<valore>\n                  Imposta una propriet\u00E0 di sistema.\n    -verbose:[class|gc|jni]\n                  Abilita l''output descrittivo.\n    -version      Visualizza la versione del prodotto ed esce.\n    -showversion  Visualizza la versione del prodotto e continua\n    -? -help      Visualizza questo messaggio della Guida.\n    -X            Visualizza la Guida relativa alle opzioni non standard.\n    -ea[:<nome package>...|:<nome classe>]\n    -enableassertions[:<nome package>...|:<nome classe>]\n                  Abilita le asserzioni con la granularit\u00E0 specificata.\n    -da[:<nome package>...|:<nome classe>]\n    -disableassertions[:<nome package>...|:<nome classe>]\n                  Disabilita le asserzioni con la granularit\u00E0 specificata.\n    -esa | -enablesystemassertions\n                  Abilita le asserzioni di sistema.\n    -dsa | -disablesystemassertions\n                  Disabilita le asserzioni di sistema.\n    -agentlib:<nome libreria>[=<opzioni>]\n                  Carica la libreria agenti nativa <nome libreria>, ad esempio -agentlib:jdwp.\n                  Vedere anche -agentlib:jdwp=help.\n    -agentpath:<nome percorso>[=<opzioni>]\n                  Carica la libreria agenti nativa con il percorso completo.\n    -javaagent:<percorso jar>[=<opzioni>]\n                  Carica l''agente del linguaggio di programmazione Java. Vedere java.lang.instrument.\n    -splash:<percorso immagine>\n                  Mostra la schermata iniziale con l''immagine specificata.\n    @<percorso file>   Legge le opzioni dal file specificato.\n
+java.launcher.opt.footer     =\    -cp <classpath di ricerca di directory e file zip/jar>\n    -classpath <classpath di ricerca di directory e file zip/jar>\n    --class-path <classpath di ricerca di directory e file zip/jar>\n               Lista separata da {0} di directory e di archivi JAR\n                  e ZIP utilizzata per la ricerca di file di classe.\n    -p <percorso modulo>\n    -module-path <percorso modulo>...\n                  Lista separata da {0} di directory; ciascuna directory\n                  \u00E8 una directory di moduli.\n    -upgrade-module-path <percorso modulo>...\n                  Lista separata da {0} di directory; ciascuna directory\n                  \u00E8 una directory dei moduli che sostituiscono i moduli\n                  aggiornabili nell''immagine in fase di esecuzione.\n    -m <modulo>[/<classe principale>]\n    --module <nome modulo>[/<classe principale>]\n                  Il modulo iniziale da risolvere e il nome della classe\n                  principale da eseguire se non specificata dal modulo.\n    -add-modules <nome modulo>[,<nome modulo>...]\n                  Moduli root da risolvere in aggiunta al modulo iniziale.\n                  <nome modulo> pu\u00F2 essere anche ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH.\n    -limit-modules <nome modulo>[,<nome modulo>...]\n                  Limita l''universe dei moduli osservabili.\n    -list-modules[:<nome modulo>[,<nome modulo>...]]\n                  Elenca i moduli osservabili ed esce.\n    --dry-run     Crea la VM ma non esegue il metodo principale.\n                  Pu\u00F2 essere utile, ad esempio, per la convalida delle opzioni della\n                  riga di comando utilizzate per la configurazione del sistema di moduli.\n    -D<nome>=<valore>\n                  Imposta una propriet\u00E0 di sistema.\n    -verbose:[class|gc|jni]\n                  Abilita l''output descrittivo.\n    -version      Visualizza la versione del prodotto ed esce.\n    -showversion  Visualizza la versione del prodotto e continua\n    -? -help      --help\n                  Visualizza questo messaggio della Guida.\n    -X            Visualizza la Guida relativa alle opzioni non standard.\n    -ea[:<nome package>...|:<nome classe>]\n    -enableassertions[:<nome package>...|:<nome classe>]\n                  Abilita le asserzioni con la granularit\u00E0 specificata.\n    -da[:<nome package>...|:<nome classe>]\n    -disableassertions[:<nome package>...|:<nome classe>]\n                  Disabilita le asserzioni con la granularit\u00E0 specificata.\n    -esa | -enablesystemassertions\n                  Abilita le asserzioni di sistema.\n    -dsa | -disablesystemassertions\n                  Disabilita le asserzioni di sistema.\n    -agentlib:<nome libreria>[=<opzioni>]\n                  Carica la libreria agenti nativa <nome libreria>, ad esempio -agentlib:jdwp.\n                  Vedere anche -agentlib:jdwp=help.\n    -agentpath:<nome percorso>[=<opzioni>]\n                  Carica la libreria agenti nativa con il percorso completo.\n    -javaagent:<percorso jar>[=<opzioni>]\n                  Carica l''agente del linguaggio di programmazione Java. Vedere java.lang.instrument.\n    -splash:<percorso immagine>\n                  Mostra la schermata iniziale con l''immagine specificata.\n                  Le immagini ridimensionate HiDPI sono supportate e utilizzate automaticamente\n                  se disponibili. I nomi file delle immagini non ridimensionate, ad esempio image.ext,\n                  devono essere sempre passati come argomenti all''opzione -splash.\n                  Verr\u00E0 scelta automaticamente l''immagine ridimensionata pi\u00F9 appropriata\n                  fornita.\n                  Per ulteriori informazioni, vedere la documentazione relativa all''API SplashScreen.\n    @<percorso file>   legge le opzioni dal file specificato.\nPer specificare un argomento per un''opzione lunga, \u00E8 possibile \
+utilizzare --<nome>=<valore> o\n--<nome> <valore>.
 See Per ulteriori dettagli, vedere http://www.oracle.com/technetwork/java/javase/documentation/index.html.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           esecuzione in modalit\u00E0 mista (impostazione predefinita)\n    -Xint             esecuzione solo in modalit\u00E0 convertita\n    -Xbootclasspath/a:<directory e file zip/jar separati da {0}>\n                      aggiunge alla fine del classpath di bootstrap\n     -Xdiag            mostra messaggi di diagnostica aggiuntivi\n    -Xdiag:resolver   mostra i messaggi di diagnostica del resolver\n    -Xnoclassgc       disabilita la garbage collection della classe\n    -Xloggc:<file>    registra lo stato GC in un file con indicatori orari\n    -Xbatch           disabilita la compilazione in background\n    -Xms<size>        imposta la dimensione heap Java iniziale\n    -Xmx<size>        imposta la dimensione heap Java massima\n    -Xss<size>        imposta la dimensione dello stack di thread Java\n    -Xprof            visualizza i dati di profilo della CPU\n    -Xfuture          abilita i controlli pi\u00F9 limitativi anticipando le impostazioni predefinite future\n    -Xrs              riduce l''uso di segnali del sistema operativo da Java/VM (vedere la documentazione)\n    -Xcheck:jni       esegue controlli aggiuntivi per le funzioni JNI\n    -Xshare:off       non tenta di utilizzare i dati della classe condivisi\n    -Xshare:auto      utilizza i dati di classe condivisi se possibile (impostazione predefinita)\n    -Xshare:on        richiede l''uso dei dati di classe condivisi, altrimenti l''esecuzione non riesce.\n    -XshowSettings    mostra tutte le impostazioni e continua\n    -XshowSettings:all\n                      mostra tutte le impostazioni e continua\n    -XshowSettings:vm mostra tutte le impostazioni correlate alla VM e continua\n    -XshowSettings:properties\n                      mostra tutte le impostazioni delle propriet\u00E0 e continua\n    -XshowSettings:locale\n                      mostra tutte le impostazioni correlate alle impostazioni nazionali e continua\n   -XaddReads:<module>=<other-module>(,<other-module>)*\n                      <module> legge altri moduli,\n                      indipendentemente dalla dichiarazione del modulo\n   -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      <module> esporta il <package> in altri moduli,\n                      indipendentemente dalla dichiarazione del modulo\n    -Xpatch:<module>=<file>({0}<file>)*\n                      sostituisce o migliora un modulo con classi e risorse\n                      in file JAR o directory\n    -Xdisable-@files  disabilita l''ulteriore espansione del file di argomenti\n\nLe opzioni -X non sono opzioni standard e sono soggette a modifiche senza preavviso.\n
+java.launcher.X.usage=\    -Xbatch           disabilita la compilazione in background\n    -Xbootclasspath/a:<directory e file zip/jar separati da {0}>\n                      aggiunge alla fine del classpath di bootstrap\n   -Xcheck:jni       esegue controlli aggiuntivi per le funzioni JNI\n    -Xcomp            forza la compilazione dei metodi al primo richiamo\n    -Xdebug           fornito per la compatibilit\u00E0 con le versioni precedenti\n    -Xdiag            mostra ulteriori messaggi diagnostici\n    -Xdiag:resolver   mostra i messaggi diagnostici del resolver\n    -Xdisable-@files  disabilita l''ulteriore espansione del file di argomenti\n    -Xfuture          abilita i controlli pi\u00F9 limitativi anticipando le impostazioni predefinite future\n    -Xint             esecuzione solo in modalit\u00E0 convertita\n    -Xinternalversion\n                      visualizza informazioni pi\u00F9 dettagliate sulla versione JVM rispetto\n                      all''opzione -version\n    -Xloggc:<file>    registra lo stato GC in un file con indicatori orari\n    -Xmixed           esecuzione in modalit\u00E0 mista (impostazione predefinita)\n    -Xmn<size>        imposta le dimensioni iniziale e massima (in byte) dell''heap\n                      per la young generation (nursery)\n    -Xms<size>        imposta la dimensione heap Java iniziale\n    -Xmx<size>        imposta la dimensione heap Java massima\n    -Xnoclassgc       disabilta la garbage collection della classe\n    -Xprof            visualizza i dati di profilo della CPU\n    -Xrs              riduce l''uso di segnali del sistema operativo da Java/VM (vedere la documentazione)\n    -Xshare:auto      utilizza i dati di classe condivisi se possibile (impostazione predefinita)\n     -Xshare:off       non tenta di utilizzare i dati di classe condivisi\n    -Xshare:on        richiede l''uso dei dati di classe condivisi, altrimenti l''esecuzione non riesce.\n    -XshowSettings    mostra tutte le impostazioni e continua\n    -XshowSettings:all\n                      mostra tutte le impostazioni e continua\n    -XshowSettings:locale\n                      mostra tutte le impostazioni correlate alle impostazioni nazionali e continua\n    -XshowSettings:properties\n                      mostra tutte le impostazioni delle propriet\u00E0 e continua\n    -XshowSettings:vm mostra tutte le impostazioni correlate alla VM e continua\n    -Xss<size>        imposta la dimensione dello stack di thread Java\n     -Xverify          imposta la modalit\u00E0 del verificatore bytecode\n    --add-reads:<module>=<target-module>(,<target-module>)*\n                      aggiorna <module> per leggere <target-module>, indipendentemente\n                      dalla dichiarazione del modulo.\n                      <target-module> pu\u00F2 essere ALL-UNNAMED per leggere tutti i\n                      moduli senza nome.\n   -add-exports:<module>/<package>=<target-module>(,<target-module>)*\n                      aggiorna <module> per esportare <package> in <target-module>,\n                      indipendentemente dalla dichiarazione del modulo.\n                      <target-module> pu\u00F2 essere ALL-UNNAMED per esportare tutti i\n                      moduli senza nome.\n    -patch-module <module>=<file>({0}<file>)*\n                      sostituisce o migliora un modulo con classi e risorse\n                      in file JAR o directory\n\nQueste opzioni non sono opzioni standard e sono soggette a modifiche senza preavviso.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\nLe opzioni riportate di seguito sono specifiche del sistema operativo Mac OS X:\n    -XstartOnFirstThread\n                      Esegue il metodo main() sul primo thread (AppKit).\n    -Xdock:name=<nome applicazione>\n                      Sostituisce il nome applicazione predefinito visualizzato nel dock\n    -Xdock:icon=<percorso file icona>\n                      Sostituisce l'icona predefinita visualizzata nel dock\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2014, 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,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   \u4F7F\u7528\u65B9\u6CD5: {0} [options] class [args...]\n           (\u30AF\u30E9\u30B9\u3092\u5B9F\u884C\u3059\u308B\u5834\u5408)\n   \u307E\u305F\u306F  {0} [options] -jar jarfile [args...]\n           (jar\u30D5\u30A1\u30A4\u30EB\u3092\u5B9F\u884C\u3059\u308B\u5834\u5408)\n   \u307E\u305F\u306F  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u3092\u5B9F\u884C\u3059\u308B\u5834\u5408)\n\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n
+java.launcher.opt.header  =   \u4F7F\u7528\u65B9\u6CD5: {0} [options] class [args...]\n           (\u30AF\u30E9\u30B9\u3092\u5B9F\u884C\u3059\u308B\u5834\u5408)\n   \u307E\u305F\u306F  {0} [options] -jar jarfile [args...]\n           (jar\u30D5\u30A1\u30A4\u30EB\u3092\u5B9F\u884C\u3059\u308B\u5834\u5408)\n   \u307E\u305F\u306F  {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u3092\u5B9F\u884C\u3059\u308B\u5834\u5408)\n\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  \u4F7F\u7528\u53EF\u80FD\u306A\u5834\u5408\u306F{0}\u30D3\u30C3\u30C8\u306E\u30C7\u30FC\u30BF\u30FB\u30E2\u30C7\u30EB\u3092\u4F7F\u7528\u3059\u308B\n
+java.launcher.opt.datamodel  =\    -d{0}\t  \u63A8\u5968\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059\n
 java.launcher.opt.vmselect   =\    {0}\t  "{1}" VM\u3092\u9078\u629E\u3059\u308B\u5834\u5408\n
 java.launcher.opt.hotspot    =\    {0}\t  \u306F"{1}" VM\u306E\u30B7\u30CE\u30CB\u30E0\u3067\u3059  [\u975E\u63A8\u5968]\n
 
@@ -34,13 +34,13 @@
 java.launcher.ergo.message2  =\                  \u3053\u308C\u306F\u30B5\u30FC\u30D0\u30FC\u30AF\u30E9\u30B9\u306E\u30DE\u30B7\u30F3\u3067\u5B9F\u884C\u3057\u3066\u3044\u308B\u305F\u3081\u3067\u3059\u3002\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n    -classpath <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n                  \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\n                  JAR\u30A2\u30FC\u30AB\u30A4\u30D6\u304A\u3088\u3073ZIP\u30A2\u30FC\u30AB\u30A4\u30D6\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3002\n    -mp <\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9>\n    -modulepath <\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9>...\n                  \u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3002\u5404\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\n                  \u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u3059\u3002\n    -upgrademodulepath <\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9>...\n                  \u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3002\u5404\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\n                  \u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30A4\u30E1\u30FC\u30B8\u3067\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u7F6E\u63DB\u3059\u308B\n                  \u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u3059\n    -m <modulename>[/<mainclass>]\n                  \u89E3\u6C7A\u3059\u308B\u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u304A\u3088\u3073\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u306B\n                  \u5B9F\u884C\u3059\u308B\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u306E\u540D\u524D\n    -addmods <modulename>[,<modulename>...]\n                  \u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\n    -limitmods <modulename>[,<modulename>...]\n                  \u76E3\u8996\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30E6\u30CB\u30D0\u30FC\u30B9\u3092\u5236\u9650\u3059\u308B\n    -listmods[:<modulename>[,<modulename>...]]\n                  \u76E3\u8996\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30EA\u30B9\u30C8\u3057\u3066\u7D42\u4E86\u3059\u308B\n    --dry-run     VM\u3092\u4F5C\u6210\u3059\u308B\u304C\u3001\u30E1\u30A4\u30F3\u30FB\u30E1\u30BD\u30C3\u30C9\u306F\u5B9F\u884C\u3057\u306A\u3044\u3002\n                  \u3053\u306E--dry-run\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u3001\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30B7\u30B9\u30C6\u30E0\u69CB\u6210\u306A\u3069\u306E\n                  \u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u691C\u8A3C\u3059\u308B\u5834\u5408\u306B\u4FBF\u5229\u3067\u3059\u3002\n    -D<name>=<value>\n                  \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n    -verbose:[class|gc|jni]\n                  \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n    -version      \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n    -showversion  \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -? -help      \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n    -X            \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3059\u308B\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  \
-\u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n    -esa | -enablesystemassertions\n                  \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n    -dsa | -disablesystemassertions\n                  \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n    -agentlib:<libname>[=<options>]\n                  \u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA<libname>\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002\u4F8B: -agentlib:jdwp\n                  -agentlib:jdwp=help\u3082\u53C2\u7167\n    -agentpath:<pathname>[=<options>]\n                  \u30D5\u30EB\u30D1\u30B9\u540D\u3067\u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\n    -javaagent:<jarpath>[=<options>]\n                  Java\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002java.lang.instrument\u3092\u53C2\u7167\n    -splash:<imagepath>\n                  \u6307\u5B9A\u3057\u305F\u30A4\u30E1\u30FC\u30B8\u3067\u30B9\u30D7\u30E9\u30C3\u30B7\u30E5\u753B\u9762\u3092\u8868\u793A\u3059\u308B\n    @<filepath>   \u6307\u5B9A\u3057\u305F\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8AAD\u307F\u53D6\u308B\n
+java.launcher.opt.footer     =\    -cp <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n    -classpath <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n    --class-path <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n                  \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\n                  JAR\u30A2\u30FC\u30AB\u30A4\u30D6\u304A\u3088\u3073ZIP\u30A2\u30FC\u30AB\u30A4\u30D6\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3002\n    -p <\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9>\n    --module-path <\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9>...\n                  \u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3002\u5404\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\n                  \u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u3059\u3002\n    --upgrade-module-path <\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9>...\n                  \u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3002\u5404\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\n                  \u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30A4\u30E1\u30FC\u30B8\u3067\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u7F6E\u63DB\u3059\u308B\n                  \u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u3059\n    -m <module>[/<mainclass>]\n    --module <modulename>[/<mainclass>]\n                  \u89E3\u6C7A\u3059\u308B\u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u304A\u3088\u3073\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u306B\n                  \u5B9F\u884C\u3059\u308B\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u306E\u540D\u524D\n    --add-modules <modulename>[,<modulename>...]\n                  \u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3002\n                  <modulename>\u306FALL-DEFAULT\u3001ALL-SYSTEM\u3001ALL-MODULE-PATH\n                  \u306B\u3059\u308B\u3053\u3068\u3082\u3067\u304D\u307E\u3059\u3002\n    --limit-modules <modulename>[,<modulename>...]\n                  \u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3059\u308B\n    --list-modules [<modulename>[,<modulename>...]]\n                  \u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u4E00\u89A7\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n    --dry-run     VM\u3092\u4F5C\u6210\u3059\u308B\u304C\u3001\u30E1\u30A4\u30F3\u30FB\u30E1\u30BD\u30C3\u30C9\u306F\u5B9F\u884C\u3057\u306A\u3044\u3002\n                  \u3053\u306E--dry-run\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u3001\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30B7\u30B9\u30C6\u30E0\u69CB\u6210\u306A\u3069\u306E\n                  \u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u691C\u8A3C\u3059\u308B\u5834\u5408\u306B\u4FBF\u5229\u3067\u3059\u3002\n    -D<name>=<value>\n                  \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n    -verbose:[class|gc|jni]\n                  \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n    -version      \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n    -showversion  \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -? -help --help\n                  \
+\u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n    -X            \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3059\u308B\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n    -esa | -enablesystemassertions\n                  \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n    -dsa | -disablesystemassertions\n                  \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n    -agentlib:<libname>[=<options>]\n                  \u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA<libname>\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002\u4F8B: -agentlib:jdwp\n                  -agentlib:jdwp=help\u3082\u53C2\u7167\n    -agentpath:<pathname>[=<options>]\n                  \u30D5\u30EB\u30D1\u30B9\u540D\u3067\u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\n    -javaagent:<jarpath>[=<options>]\n                  Java\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002java.lang.instrument\u3092\u53C2\u7167\n    -splash:<imagepath>\n                  \u6307\u5B9A\u3057\u305F\u30A4\u30E1\u30FC\u30B8\u3067\u30B9\u30D7\u30E9\u30C3\u30B7\u30E5\u753B\u9762\u3092\u8868\u793A\u3059\u308B\n                  \u53EF\u80FD\u3067\u3042\u308C\u3070\u3001HiDPI\u30B9\u30B1\u30FC\u30EB\u306E\u30A4\u30E1\u30FC\u30B8\u304C\u81EA\u52D5\u7684\u306B\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n                  \u30B9\u30B1\u30FC\u30EB\u306A\u3057\u306E\u30A4\u30E1\u30FC\u30B8\u306E\u30D5\u30A1\u30A4\u30EB\u540D(image.ext\u306A\u3069)\u306F\u3001\n                  \u5E38\u306B-splash\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u3068\u3057\u3066\u6E21\u3055\u308C\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n                  \u6307\u5B9A\u3055\u308C\u305F\u6700\u9069\u306A\u30B9\u30B1\u30FC\u30EB\u306E\u30A4\u30E1\u30FC\u30B8\u304C\u81EA\u52D5\u7684\u306B\n                  \u9078\u629E\u3055\u308C\u307E\u3059\u3002\n                  \u8A73\u7D30\u306FSplashScreen API\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n    @<filepath>   \u6307\u5B9A\u3057\u305F\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8AAD\u307F\u53D6\u308B\n\u9577\u3044\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u3092\u6307\u5B9A\u3059\u308B\u5834\u5408\u3001--<name>=<value>\u307E\u305F\u306F\n--<name> <value>\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n
 See \u8A73\u7D30\u306F\u3001http://www.oracle.com/technetwork/java/javase/documentation/index.html\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n    -Xint             \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n    -Xbootclasspath/a:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n                      \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n    -Xdiag            \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n    -Xdiag:resolver   \u30EA\u30BE\u30EB\u30D0\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n    -Xnoclassgc       \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n    -Xloggc:<file>    \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n    -Xbatch           \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n    -Xms<size>        Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n    -Xmx<size>        Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n    -Xss<size>        Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n    -Xprof            CPU\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30FC\u30BF\u3092\u51FA\u529B\u3059\u308B\n    -Xfuture          \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n    -Xrs              Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n    -Xcheck:jni       JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n    -Xshare:off       \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n    -Xshare:auto      \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n    -Xshare:on        \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n    -XshowSettings    \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:all\n                      \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:vm \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:properties\n                      \u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:locale\n                      \u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XaddReads:<module>=<other-module>(,<other-module>)*\n                      \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001\n                      <module>\u306F\u4ED6\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u8AAD\u307F\u53D6\u308B\n    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001\n               \
-       <module>\u306F<package>\u3092\u4ED6\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\n    -Xpatch:<module>=<file>({0}<file>)*\n                      JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n                      \u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3059\u308B\n    -Xdisable-@files  \u3055\u3089\u306A\u308B\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u3092\u7121\u52B9\u306B\u3059\u308B\n\n-X\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u6A19\u6E96\u306A\u306E\u3067\u3001\u4E88\u544A\u306A\u304F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\n
+java.launcher.X.usage=\    -Xbatch           \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n    -Xbootclasspath/a:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n                      \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n    -Xcheck:jni       JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n    -Xcomp            \u521D\u56DE\u547C\u51FA\u3057\u6642\u306B\u30E1\u30BD\u30C3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u5F37\u5236\u3059\u308B\n    -Xdebug           \u4E0B\u4F4D\u4E92\u63DB\u6027\u306E\u305F\u3081\u306B\u63D0\u4F9B\n    -Xdiag            \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n    -Xdiag:resolver   \u30EA\u30BE\u30EB\u30D0\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n    -Xdisable-@files  \u3055\u3089\u306A\u308B\u5F15\u6570\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u3092\u7121\u52B9\u306B\u3059\u308B\n    -Xfuture          \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n    -Xint             \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n    -Xinternalversion\n                      -version\u30AA\u30D7\u30B7\u30E7\u30F3\u3088\u308A\u8A73\u7D30\u306AJVM\u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\n                       \u8868\u793A\u3059\u308B\n    -Xloggc:<file>    \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n    -Xmixed           \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n    -Xmn<size>        \u82E5\u3044\u4E16\u4EE3(\u30CA\u30FC\u30B5\u30EA)\u306E\u30D2\u30FC\u30D7\u306E\u521D\u671F\u304A\u3088\u3073\u6700\u5927\u30B5\u30A4\u30BA(\u30D0\u30A4\u30C8\u5358\u4F4D)\n                      \u3092\u8A2D\u5B9A\u3059\u308B\n    -Xms<size>        Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n    -Xmx<size>        Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n    -Xnoclassgc       \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n    -Xprof            CPU\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30FC\u30BF\u3092\u51FA\u529B\u3059\u308B\n    -Xrs              Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n    -Xshare:auto      \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n    -Xshare:off       \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n    -Xshare:on        \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n    -XshowSettings    \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:all\n                      \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:locale\n                      \u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:properties\n                      \
+\u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -XshowSettings:vm \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n    -Xss<size>        Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n    -Xverify          \u30D0\u30A4\u30C8\u30B3\u30FC\u30C9\u691C\u8A3C\u6A5F\u80FD\u306E\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3059\u308B\n    --add-reads <module>=<target-module>(,<target-module>)*\n                      \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<target-module>\n                      \u3092\u8AAD\u307F\u53D6\u308A\u307E\u3059\u3002 \n                      <target-module>\u3092ALL-UNNAMED\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n                      \u8AAD\u307F\u53D6\u308C\u307E\u3059\u3002\n    --add-exports <module>/<package>=<target-module>(,<target-module>)*\n                      \u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306B\u95A2\u4FC2\u306A\u304F\u3001<module>\u3092\u66F4\u65B0\u3057\u3066<package>\u3092<target-module>\u306B\n                      \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\n                      <target-module>\u3092ALL-UNNAMED\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\n                      \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3067\u304D\u307E\u3059\u3002\n    --patch-module <module>=<file>({0}<file>)*\n                      JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\n                      \u62E1\u5F35\u3057\u307E\u3059\u3002\n\n\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\n\u6B21\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306FMac OS X\u56FA\u6709\u3067\u3059:\n    -XstartOnFirstThread\n                      main()\u30E1\u30BD\u30C3\u30C9\u3092\u6700\u521D(AppKit)\u306E\u30B9\u30EC\u30C3\u30C9\u3067\u5B9F\u884C\u3059\u308B\n    -Xdock:name=<application name>\n                      Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n    -Xdock:icon=<path to icon file>\n                      Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_ko.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_ko.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2014, 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,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   \uC0AC\uC6A9\uBC95: {0} [options] class [args...]\n           (\uD074\uB798\uC2A4 \uC2E4\uD589)\n   \uB610\uB294  {0} [options] -jar jarfile [args...]\n           (jar \uD30C\uC77C \uC2E4\uD589)\n   \uB610\uB294  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (\uBAA8\uB4C8\uC758 \uAE30\uBCF8 \uD074\uB798\uC2A4 \uC2E4\uD589)\n\uC5EC\uAE30\uC11C options\uB294 \uB2E4\uC74C\uACFC \uAC19\uC2B5\uB2C8\uB2E4.\n
+java.launcher.opt.header  =   \uC0AC\uC6A9\uBC95: {0} [options] class [args...]\n           (\uD074\uB798\uC2A4 \uC2E4\uD589)\n   \uB610\uB294  {0} [options] -jar jarfile [args...]\n           (jar \uD30C\uC77C \uC2E4\uD589)\n   \uB610\uB294  {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (\uBAA8\uB4C8\uC758 \uAE30\uBCF8 \uD074\uB798\uC2A4 \uC2E4\uD589)\n\uC5EC\uAE30\uC11C options\uB294 \uB2E4\uC74C\uACFC \uAC19\uC2B5\uB2C8\uB2E4.\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uACBD\uC6B0 {0}\uBE44\uD2B8 \uB370\uC774\uD130 \uBAA8\uB378\uC744 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n
+java.launcher.opt.datamodel  =\    -d{0}\t  \uB354 \uC774\uC0C1 \uC0AC\uC6A9\uB418\uC9C0 \uC54A\uC74C. \uC774\uD6C4 \uB9B4\uB9AC\uC2A4\uC5D0\uC11C \uC81C\uAC70\uB429\uB2C8\uB2E4.\n
 java.launcher.opt.vmselect   =\    {0}\t  "{1}" VM\uC744 \uC120\uD0DD\uD569\uB2C8\uB2E4.\n
 java.launcher.opt.hotspot    =\    {0}\t  "{1}" VM\uC758 \uB3D9\uC758\uC5B4\uC785\uB2C8\uB2E4[\uC0AC\uC6A9\uB418\uC9C0 \uC54A\uC74C].\n
 
@@ -34,13 +34,13 @@
 java.launcher.ergo.message2  =\                  \uC11C\uBC84\uAE09 \uC2DC\uC2A4\uD15C\uC5D0\uC11C \uC2E4\uD589 \uC911\uC774\uAE30 \uB54C\uBB38\uC785\uB2C8\uB2E4.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n    -classpath <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n                  \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uAC80\uC0C9\uD560 {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC,\n                  JAR \uC544\uCE74\uC774\uBE0C \uBC0F ZIP \uC544\uCE74\uC774\uBE0C \uBAA9\uB85D\uC785\uB2C8\uB2E4.\n    -mp <\uBAA8\uB4C8 \uACBD\uB85C>\n    -modulepath <\uBAA8\uB4C8 \uACBD\uB85C>...\n                  {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC785\uB2C8\uB2E4. \uAC01 \uB514\uB809\uD1A0\uB9AC\uB294\n                  \uBAA8\uB4C8\uC758 \uB514\uB809\uD1A0\uB9AC\uC785\uB2C8\uB2E4.\n    -upgrademodulepath <\uBAA8\uB4C8 \uACBD\uB85C>...\n                  {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC785\uB2C8\uB2E4. \uAC01 \uB514\uB809\uD1A0\uB9AC\uB294\n                  \uBAA8\uB4C8\uC758 \uB514\uB809\uD1A0\uB9AC\uB85C, \uB7F0\uD0C0\uC784 \uC774\uBBF8\uC9C0\uC5D0\uC11C \uC5C5\uADF8\uB808\uC774\uB4DC\n                  \uAC00\uB2A5\uD55C \uBAA8\uB4C8\uC744 \uB300\uCCB4\uD569\uB2C8\uB2E4.\n    -m <\uBAA8\uB4C8 \uC774\uB984>[/<\uAE30\uBCF8 \uD074\uB798\uC2A4>]\n                  \uBD84\uC11D\uD560 \uCD08\uAE30 \uBAA8\uB4C8 \uBC0F \uBAA8\uB4C8\uC5D0\uC11C \uC9C0\uC815\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0 \uC2E4\uD589\uD560\n                  \uAE30\uBCF8 \uD074\uB798\uC2A4\uC758 \uC774\uB984\uC785\uB2C8\uB2E4.\n    -addmods <\uBAA8\uB4C8 \uC774\uB984>[,<\uBAA8\uB4C8 \uC774\uB984>...]\n                  \uCD08\uAE30 \uBAA8\uB4C8 \uC678\uC5D0 \uBD84\uC11D\uD560 \uB8E8\uD2B8 \uBAA8\uB4C8\uC785\uB2C8\uB2E4.\n    -limitmods <\uBAA8\uB4C8 \uC774\uB984>[,<\uBAA8\uB4C8 \uC774\uB984>...]\n                  \uAD00\uCC30 \uAC00\uB2A5\uD55C \uBAA8\uB4C8\uC758 \uBC94\uC704\uB97C \uC81C\uD55C\uD569\uB2C8\uB2E4.\n    -listmods[:<\uBAA8\uB4C8 \uC774\uB984>[,<\uBAA8\uB4C8 \uC774\uB984>...]]\n                  \uAD00\uCC30 \uAC00\uB2A5\uD55C \uBAA8\uB4C8\uC744 \uB098\uC5F4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\n    --dry-run     VM\uC744 \uC0DD\uC131\uD558\uC9C0\uB9CC \uAE30\uBCF8 \uBA54\uC18C\uB4DC\uB97C \uC2E4\uD589\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n                  \uC774 --dry-run \uC635\uC158\uC740 \uBAA8\uB4C8 \uC2DC\uC2A4\uD15C \uAD6C\uC131\uACFC \uAC19\uC740 \uBA85\uB839\uD589\n                  \uC635\uC158\uC744 \uAC80\uC99D\uD558\uB294 \uB370 \uC720\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n    -D<\uC774\uB984>=<\uAC12>\n                  \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.\n    -verbose:[class|gc|jni]\n                  \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -version      \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\n    -showversion  \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -? -help      \uC774 \uB3C4\uC6C0\uB9D0 \uBA54\uC2DC\uC9C0\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.\n    -X            \uBE44\uD45C\uC900 \uC635\uC158\uC5D0 \uB300\uD55C \uB3C4\uC6C0\uB9D0\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.\n    -ea[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n    -enableassertions[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n                  \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -da[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n    -disableassertions[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n                  \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -esa \
-| -enablesystemassertions\n                  \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -dsa | -disablesystemassertions\n                  \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -agentlib:<\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC774\uB984>[=<\uC635\uC158>]\n                  \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC <\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC774\uB984>\uC744 \uB85C\uB4DC\uD569\uB2C8\uB2E4(\uC608: -agentlib:jdwp).\n                  -agentlib:jdwp=help\uB3C4 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n    -agentpath:<\uACBD\uB85C \uC774\uB984>[=<\uC635\uC158>]\n                  \uC804\uCCB4 \uACBD\uB85C \uC774\uB984\uC744 \uC0AC\uC6A9\uD558\uC5EC \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4.\n    -javaagent:<jar \uACBD\uB85C>[=<\uC635\uC158>]\n                  Java \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4 \uC5D0\uC774\uC804\uD2B8\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4. java.lang.instrument\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n    -splash:<\uC774\uBBF8\uC9C0 \uACBD\uB85C>\n                  \uC774\uBBF8\uC9C0\uAC00 \uC9C0\uC815\uB41C \uC2A4\uD50C\uB798\uC2DC \uD654\uBA74\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n    @<\uD30C\uC77C \uACBD\uB85C>   \uC9C0\uC815\uB41C \uD30C\uC77C\uC5D0\uC11C \uC635\uC158\uC744 \uC77D\uC2B5\uB2C8\uB2E4.\n
+java.launcher.opt.footer     =\    -cp <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n    -classpath <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n    --class-path <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n                  \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uAC80\uC0C9\uD560 {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC,\n                  JAR \uC544\uCE74\uC774\uBE0C \uBC0F ZIP \uC544\uCE74\uC774\uBE0C \uBAA9\uB85D\uC785\uB2C8\uB2E4.\n    -p <\uBAA8\uB4C8 \uACBD\uB85C>\n    --module-path <\uBAA8\uB4C8 \uACBD\uB85C>...\n                  {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC785\uB2C8\uB2E4. \uAC01 \uB514\uB809\uD1A0\uB9AC\uB294\n                  \uBAA8\uB4C8\uC758 \uB514\uB809\uD1A0\uB9AC\uC785\uB2C8\uB2E4.\n    --upgrade-module-path <\uBAA8\uB4C8 \uACBD\uB85C>...\n                  {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC785\uB2C8\uB2E4. \uAC01 \uB514\uB809\uD1A0\uB9AC\uB294\n                  \uBAA8\uB4C8\uC758 \uB514\uB809\uD1A0\uB9AC\uB85C, \uB7F0\uD0C0\uC784 \uC774\uBBF8\uC9C0\uC5D0\uC11C \uC5C5\uADF8\uB808\uC774\uB4DC\n                  \uAC00\uB2A5\uD55C \uBAA8\uB4C8\uC744 \uB300\uCCB4\uD569\uB2C8\uB2E4.\n    -m <\uBAA8\uB4C8>[/<\uAE30\uBCF8 \uD074\uB798\uC2A4>]\n    --module <\uBAA8\uB4C8 \uC774\uB984>[/<\uAE30\uBCF8 \uD074\uB798\uC2A4>]\n                  \uBD84\uC11D\uD560 \uCD08\uAE30 \uBAA8\uB4C8 \uBC0F \uBAA8\uB4C8\uC5D0\uC11C \uC9C0\uC815\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0 \uC2E4\uD589\uD560\n                  \uAE30\uBCF8 \uD074\uB798\uC2A4\uC758 \uC774\uB984\uC785\uB2C8\uB2E4.\n    --add-modules <\uBAA8\uB4C8 \uC774\uB984>[,<\uBAA8\uB4C8 \uC774\uB984>...]\n                  \uCD08\uAE30 \uBAA8\uB4C8 \uC678\uC5D0 \uBD84\uC11D\uD560 \uB8E8\uD2B8 \uBAA8\uB4C8\uC785\uB2C8\uB2E4.\n                  <\uBAA8\uB4C8 \uC774\uB984>\uC740 ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH\uC77C \uC218\uB3C4 \uC788\uC2B5\uB2C8\uB2E4.\n    --limit-modules <\uBAA8\uB4C8 \uC774\uB984>[,<\uBAA8\uB4C8 \uC774\uB984>...]\n                  \uAD00\uCC30 \uAC00\uB2A5\uD55C \uBAA8\uB4C8\uC758 \uBC94\uC704\uB97C \uC81C\uD55C\uD569\uB2C8\uB2E4.\n    --list-modules [<\uBAA8\uB4C8 \uC774\uB984>[,<\uBAA8\uB4C8 \uC774\uB984>...]]\n                  \uAD00\uCC30 \uAC00\uB2A5\uD55C \uBAA8\uB4C8\uC744 \uB098\uC5F4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\n    --dry-run     VM\uC744 \uC0DD\uC131\uD558\uC9C0\uB9CC \uAE30\uBCF8 \uBA54\uC18C\uB4DC\uB97C \uC2E4\uD589\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n                  \uC774 --dry-run \uC635\uC158\uC740 \uBAA8\uB4C8 \uC2DC\uC2A4\uD15C \uAD6C\uC131\uACFC \uAC19\uC740 \uBA85\uB839\uD589\n                  \uC635\uC158\uC744 \uAC80\uC99D\uD558\uB294 \uB370 \uC720\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n    -D<\uC774\uB984>=<\uAC12>\n                  \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.\n    -verbose:[class|gc|jni]\n                  \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -version      \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\n    -showversion  \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -? -help --help\n                  \uC774 \uB3C4\uC6C0\uB9D0 \uBA54\uC2DC\uC9C0\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.\n    -X            \uBE44\uD45C\uC900 \uC635\uC158\uC5D0 \uB300\uD55C \uB3C4\uC6C0\uB9D0\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.\n    -ea[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n    -enableassertions[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n                  \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \
+\uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -da[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n    -disableassertions[:<\uD328\uD0A4\uC9C0 \uC774\uB984>...|:<\uD074\uB798\uC2A4 \uC774\uB984>]\n                  \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -esa | -enablesystemassertions\n                  \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -dsa | -disablesystemassertions\n                  \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -agentlib:<\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC774\uB984>[=<\uC635\uC158>]\n                  \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC <\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC774\uB984>\uC744 \uB85C\uB4DC\uD569\uB2C8\uB2E4(\uC608: -agentlib:jdwp).\n                  -agentlib:jdwp=help\uB3C4 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n    -agentpath:<\uACBD\uB85C \uC774\uB984>[=<\uC635\uC158>]\n                  \uC804\uCCB4 \uACBD\uB85C \uC774\uB984\uC744 \uC0AC\uC6A9\uD558\uC5EC \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4.\n    -javaagent:<jar \uACBD\uB85C>[=<\uC635\uC158>]\n                  Java \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4 \uC5D0\uC774\uC804\uD2B8\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4. java.lang.instrument\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n    -splash:<\uC774\uBBF8\uC9C0 \uACBD\uB85C>\n                  \uC774\uBBF8\uC9C0\uAC00 \uC9C0\uC815\uB41C \uC2A4\uD50C\uB798\uC2DC \uD654\uBA74\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n                  HiDPI\uB85C \uC870\uC815\uB41C \uC774\uBBF8\uC9C0\uAC00 \uC790\uB3D9\uC73C\uB85C \uC9C0\uC6D0\uB418\uACE0 \uAC00\uB2A5\uD55C \uACBD\uC6B0\n                  \uC0AC\uC6A9\uB429\uB2C8\uB2E4. \uBBF8\uC870\uC815 \uC774\uBBF8\uC9C0 \uD30C\uC77C \uC774\uB984(\uC608: image.ext)\uC740\n                  \uD56D\uC0C1 -splash \uC635\uC158\uC5D0 \uC778\uC218\uB85C \uC804\uB2EC\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.\n                  \uAC00\uC7A5 \uC801\uC808\uD788 \uC870\uC815\uB41C \uC774\uBBF8\uC9C0\uAC00 \uC790\uB3D9\uC73C\uB85C \uCC44\uD0DD\uB429\uB2C8\uB2E4.\n                  \uC790\uC138\uD55C \uB0B4\uC6A9\uC740 SplashScreen API \uC124\uBA85\uC11C\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n    @<\uD30C\uC77C \uACBD\uB85C>   \uC9C0\uC815\uB41C \uD30C\uC77C\uC5D0\uC11C \uC635\uC158\uC744 \uC77D\uC2B5\uB2C8\uB2E4.\nlong \uC635\uC158\uC5D0 \uB300\uD55C \uC778\uC218\uB97C \uC9C0\uC815\uD558\uB824\uBA74 --<\uC774\uB984>=<\uAC12> \uB610\uB294 --<\uC774\uB984> <\uAC12>\uC744\n\uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n
 See \uC790\uC138\uD55C \uB0B4\uC6A9\uC740 http://www.oracle.com/technetwork/java/javase/documentation/index.html\uC744 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           \uD63C\uD569 \uBAA8\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n    -Xint             \uD574\uC11D\uB41C \uBAA8\uB4DC\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4.\n    -Xbootclasspath/a:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n                      \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uB05D\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n    -Xdiag            \uCD94\uAC00 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n    -Xdiag:resolver   \uBD84\uC11D\uAE30 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n    -Xnoclassgc       \uD074\uB798\uC2A4\uC758 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xloggc:<file>    \uC2DC\uAC04 \uAE30\uB85D\uACFC \uD568\uAED8 \uD30C\uC77C\uC5D0 GC \uC0C1\uD0DC\uB97C \uAE30\uB85D\uD569\uB2C8\uB2E4.\n    -Xbatch           \uBC31\uADF8\uB77C\uC6B4\uB4DC \uCEF4\uD30C\uC77C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xms<size>        \uCD08\uAE30 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xmx<size>        \uCD5C\uB300 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xss<size>        Java \uC2A4\uB808\uB4DC \uC2A4\uD0DD \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xprof            CPU \uD504\uB85C\uD30C\uC77C \uC791\uC131 \uB370\uC774\uD130\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4.\n    -Xfuture          \uBBF8\uB798 \uAE30\uBCF8\uAC12\uC744 \uC608\uCE21\uD558\uC5EC \uAC00\uC7A5 \uC5C4\uACA9\uD55C \uAC80\uC0AC\uB97C \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xrs              Java/VM\uC5D0 \uC758\uD55C OS \uC2E0\uD638 \uC0AC\uC6A9\uC744 \uC904\uC785\uB2C8\uB2E4(\uC124\uBA85\uC11C \uCC38\uC870).\n    -Xcheck:jni       JNI \uD568\uC218\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAC80\uC0AC\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n    -Xshare:off       \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130 \uC0AC\uC6A9\uC744 \uC2DC\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n    -Xshare:auto      \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n    -Xshare:on        \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uC2E4\uD328\uD569\uB2C8\uB2E4.\n    -XshowSettings    \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:all\n                      \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:vm \uBAA8\uB4E0 VM \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:properties\n                      \uBAA8\uB4E0 \uC18D\uC131 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:locale\n                      \uBAA8\uB4E0 \uB85C\uCF00\uC77C \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XaddReads:<module>=<other-module>(,<other-module>)*\n                      <module>\uC740 \uBAA8\uB4C8 \uC120\uC5B8\uC5D0 \uAD00\uACC4\uC5C6\uC774\n                      \uB2E4\uB978 \uBAA8\uB4C8\uC744 \uC77D\uC2B5\uB2C8\uB2E4.\n    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      <module>\uC740 \uBAA8\uB4C8 \uC120\uC5B8\uC5D0 \uAD00\uACC4\uC5C6\uC774\n                      <package>\uB97C \uB2E4\uB978 \uBAA8\uB4C8\uB85C \uC775\uC2A4\uD3EC\uD2B8\uD569\uB2C8\uB2E4.\n    -Xpatch:<module>=<file>({0}<file>)*\n                      JAR \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC\uC758 \uD074\uB798\uC2A4\uC640 \uB9AC\uC18C\uC2A4\uB85C\n                      \uBAA8\uB4C8\uC744 \
-\uBB34\uD6A8\uD654\uD558\uAC70\uB098 \uC778\uC218\uD654\uD569\uB2C8\uB2E4.\n    -Xdisable-@files  \uCD94\uAC00 \uC778\uC218 \uD30C\uC77C \uD655\uC7A5\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n\n-X \uC635\uC158\uC740 \uBE44\uD45C\uC900 \uC635\uC158\uC774\uBBC0\uB85C \uD1B5\uC9C0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n
+java.launcher.X.usage=\    -Xbatch           \uBC31\uADF8\uB77C\uC6B4\uB4DC \uCEF4\uD30C\uC77C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xbootclasspath/a:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n                      \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uB05D\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n    -Xcheck:jni       JNI \uD568\uC218\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAC80\uC0AC\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n    -Xcomp            \uCCAB\uBC88\uC9F8 \uD638\uCD9C\uC5D0\uC11C \uBA54\uC18C\uB4DC \uCEF4\uD30C\uC77C\uC744 \uAC15\uC81C\uD569\uB2C8\uB2E4.\n    -Xdebug           \uC5ED \uD638\uD658\uC131\uC744 \uC704\uD574 \uC81C\uACF5\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n    -Xdiag            \uCD94\uAC00 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n    -Xdiag:resolver   \uBD84\uC11D\uAE30 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n    -Xdisable-@files  \uCD94\uAC00 \uC778\uC218 \uD30C\uC77C \uD655\uC7A5\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xfuture          \uBBF8\uB798 \uAE30\uBCF8\uAC12\uC744 \uC608\uCE21\uD558\uC5EC \uAC00\uC7A5 \uC5C4\uACA9\uD55C \uAC80\uC0AC\uB97C \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xint             \uD574\uC11D\uB41C \uBAA8\uB4DC\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4.\n    -Xinternalversion\n                      -version \uC635\uC158\uBCF4\uB2E4 \uC0C1\uC138\uD55C JVM \uBC84\uC804 \uC815\uBCF4\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n    -Xloggc:<file>    \uC2DC\uAC04 \uAE30\uB85D\uACFC \uD568\uAED8 \uD30C\uC77C\uC5D0 GC \uC0C1\uD0DC\uB97C \uAE30\uB85D\uD569\uB2C8\uB2E4.\n    -Xmixed           \uD63C\uD569 \uBAA8\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n    -Xmn<size>        \uC80A\uC740 \uC138\uB300(Nursery)\uB97C \uC704\uD574 \uD799\uC758 \uCD08\uAE30 \uBC0F \uCD5C\uB300\n                      \uD06C\uAE30(\uBC14\uC774\uD2B8)\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xms<size>        \uCD08\uAE30 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xmx<size>        \uCD5C\uB300 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xnoclassgc       \uD074\uB798\uC2A4\uC758 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xprof            CPU \uD504\uB85C\uD30C\uC77C \uC791\uC131 \uB370\uC774\uD130\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4.\n    -Xrs              Java/VM\uC5D0 \uC758\uD55C OS \uC2E0\uD638 \uC0AC\uC6A9\uC744 \uC904\uC785\uB2C8\uB2E4(\uC124\uBA85\uC11C \uCC38\uC870).\n    -Xshare:auto      \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n    -Xshare:off       \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130 \uC0AC\uC6A9\uC744 \uC2DC\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n    -Xshare:on        \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uC2E4\uD328\uD569\uB2C8\uB2E4.\n    -XshowSettings    \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:all\n                      \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:locale\n                      \uBAA8\uB4E0 \uB85C\uCF00\uC77C \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:properties\n                      \uBAA8\uB4E0 \uC18D\uC131 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -XshowSettings:vm \uBAA8\uB4E0 VM \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n    -Xss<size>        Java \uC2A4\uB808\uB4DC \uC2A4\uD0DD \
+\uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    -Xverify          \uBC14\uC774\uD2B8\uCF54\uB4DC \uAC80\uC99D\uC790\uC758 \uBAA8\uB4DC\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n    --add-reads <module>=<target-module>(,<target-module>)*\n                      \uBAA8\uB4C8 \uC120\uC5B8\uC5D0 \uAD00\uACC4\uC5C6\uC774 <target-module>\uC744 \uC77D\uB3C4\uB85D\n                      <module>\uC744 \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n                      <target-module>\uC740 \uC774\uB984\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC740 \uBAA8\uB4E0 \uBAA8\uB4C8\uC744 \uC77D\uC744 \uC218 \uC788\uB294\n                      ALL-UNNAMED\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n    --add-exports <module>/<package>=<target-module>(,<target-module>)*\n                      \uBAA8\uB4C8 \uC120\uC5B8\uC5D0 \uAD00\uACC4\uC5C6\uC774 <package>\uB97C <target-module>\uB85C \uC775\uC2A4\uD3EC\uD2B8\uD558\uB3C4\uB85D\n                      <module>\uC744 \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n                      <target-module>\uC740 \uC774\uB984\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC740 \uBAA8\uB4E0 \uBAA8\uB4C8\uB85C \uC775\uC2A4\uD3EC\uD2B8\uD560 \uC218 \uC788\uB294\n                      ALL-UNNAMED\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n    --patch-module <module>=<file>({0}<file>)*\n                      JAR \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC\uC758 \uD074\uB798\uC2A4\uC640 \uB9AC\uC18C\uC2A4\uB85C\n                      \uBAA8\uB4C8\uC744 \uBB34\uD6A8\uD654\uD558\uAC70\uB098 \uC778\uC218\uD654\uD569\uB2C8\uB2E4.\n\n\uC774 \uC635\uC158\uC740 \uBE44\uD45C\uC900 \uC635\uC158\uC774\uBBC0\uB85C \uD1B5\uC9C0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\n\uB2E4\uC74C\uC740 Mac OS X\uC5D0 \uD2B9\uC815\uB41C \uC635\uC158\uC785\uB2C8\uB2E4.\n    -XstartOnFirstThread\n                      \uCCAB\uBC88\uC9F8 (AppKit) \uC2A4\uB808\uB4DC\uC5D0 main() \uBA54\uC18C\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.\n    -Xdock:name=<application name>\n                      \uACE0\uC815\uC73C\uB85C \uD45C\uC2DC\uB41C \uAE30\uBCF8 \uC560\uD50C\uB9AC\uCF00\uC774\uC158 \uC774\uB984\uC744 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n    -Xdock:icon=<path to icon file>\n                      \uACE0\uC815\uC73C\uB85C \uD45C\uC2DC\uB41C \uAE30\uBCF8 \uC544\uC774\uCF58\uC744 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_pt_BR.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_pt_BR.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   Uso: {0} [options] class [args...]\n           (para executar uma classe)\n   ou  {0} [options] -jar jarfile [args...]\n           (para executar um arquivo jar)\n   ou  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (para executar a classe principal em um m\u00F3dulo)\nem que as op\u00E7\u00F5es incluem:\n
+java.launcher.opt.header  =   Uso: {0} [options] class [args...]\n           (para executar uma classe)\n   ou  {0} [options] -jar jarfile [args...]\n           (para executar um arquivo jar)\n   or  {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (para executar a classe principal em um m\u00F3dulo)\nem que as op\u00E7\u00F5es incluem:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  usar um modelo de dados de {0} bits, se estiver dispon\u00EDvel\n
+java.launcher.opt.datamodel  =\    -d{0}\t  Obsoleto, ser\u00E1 removido em uma futura release\n
 java.launcher.opt.vmselect   =\    {0}\t  para selecionar a VM "{1}"\n
 java.launcher.opt.hotspot    =\    {0}\t  \u00E9 um sin\u00F4nimo da VM "{1}" [obsoleto]\n
 
@@ -34,11 +34,12 @@
 java.launcher.ergo.message2  =\                  porque a execu\u00E7\u00E3o est\u00E1 sendo feita em uma m\u00E1quina de classe de servidor.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <caminho de pesquisa de classe de diret\u00F3rios e arquivos zip/jar>\n    -classpath <caminho de pesquisa de classe de diret\u00F3rios e arquivos zip/jar>\n                  Uma lista separada por {0} de diret\u00F3rios, arquivos compactados JAR\n                  e arquivos compactados ZIP para procurar arquivos de classe.\n    -mp <caminho do m\u00F3dulo>\n    -modulepath <caminho do m\u00F3dulo>...\n                  Uma lista separada por {0} de diret\u00F3rios, cada um\n                  sendo um diret\u00F3rio de m\u00F3dulos.\n    -upgrademodulepath <caminho do m\u00F3dulo>...\n                  Uma lista separada por {0} de diret\u00F3rios, cada um\n                  sendo um diret\u00F3rio de m\u00F3dulos que substituem m\u00F3dulos\n                  pass\u00EDveis de upgrade na imagem de runtime\n    -m <modulename>[/<mainclass>]\n                  o m\u00F3dulo inicial a ser resolvido e o nome da classe principal\n                  a ser executada se n\u00E3o for especificada pelo m\u00F3dulo\n    -addmods <modulename>[,<modulename>...]\n                  m\u00F3dulos raiz a serem resolvidos al\u00E9m do m\u00F3dulo inicial\n    -limitmods <modulename>[,<modulename>...]\n                  limita o universo de m\u00F3dulos observ\u00E1veis\n    -listmods[:<modulename>[,<modulename>...]]\n                  lista os m\u00F3dulos observ\u00E1veis e sai\n    --dry-run     cria a VM, mas n\u00E3o executa o m\u00E9todo principal.\n                  Esta op\u00E7\u00E3o -dry-run pode ser \u00FAtil para validar as\n                  op\u00E7\u00F5es de linha de comando como a configura\u00E7\u00E3o do sistema do m\u00F3dulo\n    -D<name>=<value>\n                  define uma propriedade de sistema\n    -verbose:[class|gc|jni]\n                  ativa sa\u00EDda detalhada\n    -version      imprime a vers\u00E3o do produto e sai\n    -showversion  imprime a vers\u00E3o do produto e continua\n    -? -help      imprime esta mensagem de ajuda\n    -X            imprime a ajuda em op\u00E7\u00F5es n\u00E3o padronizadas\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  ativa asser\u00E7\u00F5es com granularidade especificada\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  desativa asser\u00E7\u00F5es com granularidade especificada\n    -esa | -enablesystemassertions\n                  ativa asser\u00E7\u00F5es do sistema\n    -dsa | -disablesystemassertions\n                  desativa asser\u00E7\u00F5es do sistema\n    -agentlib:<libname>[=<options>]\n                  carrega a biblioteca de agente nativo <libname>, por exemplo, -agentlib:jdwp\n                  consulte tamb\u00E9m -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  carrega a biblioteca de agente nativo por nome do caminho completo\n    -javaagent:<jarpath>[=<options>]\n                  carrega o agente de linguagem de programa\u00E7\u00E3o Java; consulte java.lang.instrument\n    -splash:<imagepath>\n                  mostra a tela inicial com a imagem especificada\n    @<filepath>   op\u00E7\u00F5es de leitura do arquivo especificado\n
+java.launcher.opt.footer     =\    -cp <caminho da pesquisa de classe de diret\u00F3rios e arquivos zip/jar>\n    -classpath <caminho da pesquisa de classe de diret\u00F3rios e arquivos zip/jar>\n    --class-path <caminho da pesquisa de classe de diret\u00F3rios e arquivos zip/jar>\n                  Uma lista separada por {0} de diret\u00F3rios, arquivos compactados JAR\n                  e ZIP para pesquisa de arquivos de classe.\n    -p <caminho do m\u00F3dulo>\n    --module-path <caminho do m\u00F3dulo>...\n                  Uma lista separada por {0} de diret\u00F3rios, cada um\n                  sendo um diret\u00F3rio de m\u00F3dulos.\n    --upgrade-module-path <caminho do m\u00F3dulo>...\n                  Uma lista separada por {0} de diret\u00F3rios, cada um sendo\n                  um diret\u00F3rio de m\u00F3dulos que substituem m\u00F3dulos atualiz\u00E1veis\n                  por upgrade na imagem do runtime\n    -m <module>[/<mainclass>]\n    --module <modulename>[/<mainclass>]\n                  o m\u00F3dulo inicial a ser resolvido e o nome da classe principal\n                  a ser executada se o m\u00F3dulo n\u00E3o especificar\n    --add-modules <modulename>[,<modulename>...]\n                  m\u00F3dulos-raiz a serem resolvidos al\u00E9m do m\u00F3dulo inicial.\n                  <modulename> tamb\u00E9m pode ser ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH.\n    --limit-modules <modulename>[,<modulename>...]\n                  limitar o universo de m\u00F3dulos observ\u00E1veis\n    --list-modules [<modulename>[,<modulename>...]]\n                  listar os m\u00F3dulos observ\u00E1veis e sair\n    --dry-run     criar VM, mas n\u00E3o executar o m\u00E9todo principal.\n                  Esta op\u00E7\u00E3o --dry-run pode ser \u00FAtil para validar as\n                  op\u00E7\u00F5es da linha de comando, como a configura\u00E7\u00E3o do sistema do m\u00F3dulo.\n    -D<name>=<value>\n                  definir uma propriedade do sistema\n    -verbose:[class|gc|jni]\n                  ativar sa\u00EDda detalhada\n    -version      imprimir vers\u00E3o do produto e sair\n    -showversion  imprimir vers\u00E3o do produto e continuar\n    -? -help --help\n                  imprimir esta mensagem de ajuda\n    -X            imprimir a ajuda em op\u00E7\u00F5es n\u00E3o padr\u00E3o\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  ativar asser\u00E7\u00F5es com granularidade especificada\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  desativar asser\u00E7\u00F5es com granularidade especificada\n    -esa | -enablesystemassertions\n                  ativar asser\u00E7\u00F5es do sistema\n    -dsa | -disablesystemassertions\n                  desativar asser\u00E7\u00F5es do sistema\n    -agentlib:<libname>[=<options>]\n                  carregar biblioteca de agentes nativa <libname>; por exemplo, -agentlib:jdwp\n                  consulte tamb\u00E9m -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  carregar biblioteca de agentes nativa por nome de caminho completo\n    -javaagent:<jarpath>[=<options>]\n                  carregar agente de linguagem de programa\u00E7\u00E3o Java; consulte java.lang.instrument\n    -splash:<imagepath>\n                  mostrar tela de abertura com imagem especificada\n                  Imagens HiDPI dimensionadas s\u00E3o suportadas automaticamente e utilizadas\n                  se dispon\u00EDveis. O nome do arquivo de imagem n\u00E3o dimensionada, por exemplo, image.ext,\n                  deve ser informado sempre como argumento para a op\u00E7\u00E3o -splash.\n                  A imagem dimensionada mais apropriada fornecida ser\u00E1 selecionada\n                  automaticamente.\n                  Consulte a documenta\u00E7\u00E3o da API de Tela de Abertura para obter mais \
+informa\u00E7\u00F5es.\n    @<filepath>   op\u00E7\u00F5es de leitura do arquivo especificado\nPara especificar um argumento para uma op\u00E7\u00E3o longa, voc\u00EA pode usar --<name>=<value> ou\n--<name> <value>.\n
 See http://www.oracle.com/technetwork/java/javase/documentation/index.html para obter mais detalhes.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           execu\u00E7\u00E3o no modo misto (padr\u00E3o)\n    -Xint             execu\u00E7\u00E3o somente no modo interpretado\n    -Xbootclasspath:<diret\u00F3rios e arquivos zip/jar separados por {0}>\n                      anexos ao final do caminho de classe de inicializa\u00E7\u00E3o\n    -Xdiag            mostra mensagens de diagn\u00F3stico adicionais\n    -Xdiag:resolver   mostra mensagens de diagn\u00F3stico do resolvedor\n    -Xnoclassgc       desativa a coleta de lixo da classe\n    -Xloggc:<arquivo>    registra o status do GC status em um arquivo com marca\u00E7\u00F5es de data e hor\u00E1rio\n    -Xbatch           desativa a compila\u00E7\u00E3o em segundo plano\n    -Xms<tamanho>        define o tamanho inicial do heap Java\n    -Xmx<tamanho>        define o tamanho m\u00E1ximo do heap Java\n    -Xss<tamanho>        define o tamanho da pilha de threads java\n    -Xprof            produz dados de perfil da cpu\n    -Xfuture          ativa verifica\u00E7\u00F5es de n\u00EDvel m\u00E1ximo de exig\u00EAncia, prevendo o valor padr\u00E3o futuro\n    -Xrs              reduz o uso de sinais do SO pelo(a) Java/VM (consulte a documenta\u00E7\u00E3o)\n    -Xcheck:jni       executa verifica\u00E7\u00F5es adicionais de fun\u00E7\u00F5es da JNI\n    -Xshare:off       n\u00E3o tenta usar dados da classe compartilhada\n    -Xshare:auto      se poss\u00EDvel, usa dados da classe compartilhada (padr\u00E3o)\n    -Xshare:on        requer o uso de dados da classe compartilhada, caso contr\u00E1rio haver\u00E1 falha.\n    -XshowSettings    mostra todas as defini\u00E7\u00F5es e continua\n    -XshowSettings:all\n                      mostra todas as defini\u00E7\u00F5es e continua\n    -XshowSettings:vm mostra todas as defini\u00E7\u00F5es relacionadas \u00E0 vm e continua\n    -XshowSettings:properties\n                      mostra todas as defini\u00E7\u00F5es da propriedade e continua\n    -XshowSettings:locale\n                      mostra todas as defini\u00E7\u00F5es relativas \u00E0s configura\u00E7\u00F5es regionais e continua\n    -XaddReads:<module>=<other-module>(,<other-module>)*\n                      <module> l\u00EA outros m\u00F3dulos,\n                      n\u00E3o importando a declara\u00E7\u00E3o do m\u00F3dulo\n    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      <module> exporta <package> para outros m\u00F3dulos,\n                      n\u00E3o importando a declara\u00E7\u00E3o do m\u00F3dulo\n    -Xpatch:<module>=<file>({0}<file>)*\n                      Substitui ou aumenta um m\u00F3dulo com classes e recursos\n                      em arquivos JAR ou diret\u00F3rios\n    -Xdisable-@files  desativa uma expans\u00E3o adicional de arquivo de argumentos\n\nAs op\u00E7\u00F5es -X n\u00E3o s\u00E3o padronizadas e est\u00E3o sujeitas a altera\u00E7\u00F5es sem aviso.\n
+java.launcher.X.usage=\    -Xbatch           desativar compila\u00E7\u00E3o em segundo plano\n    -Xbootclasspath/a:<diret\u00F3rios e arquivos zip/jar separados por {0}>\n                      anexar ao final do caminho de classe bootstrap\n    -Xcheck:jni       executar verifica\u00E7\u00F5es adicionais de fun\u00E7\u00F5es JNI\n    -Xcomp            for\u00E7a a compila\u00E7\u00E3o de m\u00E9todos na primeira chamada\n    -Xdebug           fornecido para fins de compatibilidade reversa\n    -Xdiag            mostrar mensagens de diagn\u00F3stico adicionais\n    -Xdiag:resolver   mostrar mensagens de diagn\u00F3stico do resolvedor\n    -Xdisable-@files  desativar expans\u00E3o de arquivo de argumento adicional\n    -Xfuture          ativar verifica\u00E7\u00F5es mais rigorosas, antecipando padr\u00E3o futuro\n    -Xint             somente execu\u00E7\u00E3o em modo interpretado\n    -Xinternalversion\n                      exibe informa\u00E7\u00F5es mais detalhadas de vers\u00E3o da JVM do que a\n                      op\u00E7\u00E3o -version\n    -Xloggc:<file>    registrar status de GC em um arquivo com time-stamps\n    -Xmixed           execu\u00E7\u00E3o em modo misto (padr\u00E3o)\n    -Xmn<size>        define o tamanho inicial e m\u00E1ximo (em bytes) do heap\n                      para a gera\u00E7\u00E3o jovem (infantil)\n    -Xms<size>        definir tamanho do heap Java inicial\n    -Xmx<size>        definir tamanho do heap Java m\u00E1ximo\n    -Xnoclassgc       desativar coleta de lixo de classe\n    -Xprof            emitir dados de perfil de cpu\n    -Xrs              reduzir uso de sinais do SO por Java/VM (consultar documenta\u00E7\u00E3o)\n    -Xshare:auto      usar dados de classe compartilhados, se poss\u00EDvel (padr\u00E3o)\n    -Xshare:off       n\u00E3o tentar usar dados de classe compartilhados\n    -Xshare:on        exigir o uso de dados de classe compartilhados; caso contr\u00E1rio, falhar\u00E1.\n    -XshowSettings    mostrar todas as defini\u00E7\u00F5es e continuar\n    -XshowSettings:all\n                      mostrar todas as defini\u00E7\u00F5es e continuar\n    -XshowSettings:locale\n                      mostrar todas as defini\u00E7\u00F5es relativas a localidade e continuar\n    -XshowSettings:properties\n                      mostrar todas as defini\u00E7\u00F5es de propriedade e continuar\n    -XshowSettings:vm mostrar todas as defini\u00E7\u00F5es relativas a vm e continuar\n    -Xss<size>        definir tamanho de pilha de thread java\n    -Xverify          define o modo do verificador de c\u00F3digo de byte\n    --add-reads <module>=<target-module>(,<target-module>)*\n                      atualiza <module> para ler <target-module>, independentemente\n                      da declara\u00E7\u00E3o do m\u00F3dulo. \n                      <target-module> pode ser ALL-UNNAMED para ler todos os m\u00F3dulos\n                      sem nome.\n    --add-exports <module>/<package>=<target-module>(,<target-module>)*\n                      atualiza <module> para exportar <package> para <target-module>,\n                      independentemente da declara\u00E7\u00E3o do m\u00F3dulo.\n                      <target-module> pode ser ALL-UNNAMED para exportar para todos\n                      os m\u00F3dulos sem nome.\n    --patch-module <module>=<file>({0}<file>)*\n                      Substituir ou aumentar um m\u00F3dulo com classes e recursos\n                      em arquivo JAR ou diret\u00F3rios.\n\nEssas op\u00E7\u00F5es n\u00E3o s\u00E3o padr\u00E3o e est\u00E3o sujeitas a altera\u00E7\u00E3o sem aviso.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\nAs op\u00E7\u00F5es a seguir s\u00E3o espec\u00EDficas para o Mac OS X:\n    -XstartOnFirstThread\n                      executa o m\u00E9todo main() no primeiro thread (AppKit)\n    -Xdock:name=<nome do aplicativo>\n                      substitui o nome do aplicativo padr\u00E3o exibido no encaixe\n    -Xdock:icon=<caminho para o arquivo do \u00EDcone>\n                      substitui o \u00EDcone exibido no encaixe\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_sv.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_sv.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   Syntax: {0} [options] class [args...]\n           (f\u00F6r att k\u00F6ra en klass)\n   eller  {0} [options] -jar jarfile [args...]\n           (f\u00F6r att k\u00F6ra en jar-fil)\n   eller {0} [options] -mp <moduls\u00F6kv\u00E4g> -m <modulnamn>[/<huvudklass>] [args...]\n           (f\u00F6r att k\u00F6ra huvudklassen i en modul)\nmed alternativen:\n
+java.launcher.opt.header  =   Syntax: {0} [options] class [args...]\n           (f\u00F6r att k\u00F6ra en klass)\n   eller  {0} [options] -jar jarfile [args...]\n           (f\u00F6r att k\u00F6ra en jar-fil)\n   eller {0} [options] -p <moduls\u00F6kv\u00E4g> -m <modulnamn>[/<huvudklass>] [args...]\n           (f\u00F6r att k\u00F6ra huvudklassen i en modul)\nmed alternativen:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  anv\u00E4nd en {0}-bitsdatamodell om det finns\n
+java.launcher.opt.datamodel  =\    -d{0}\t  Inaktuellt, tas bort i en framtida utg\u00E5va\n
 java.launcher.opt.vmselect   =\    {0}\t  f\u00F6r att v\u00E4lja "{1}" VM\n
 java.launcher.opt.hotspot    =\    {0}\t  \u00E4r en synonym f\u00F6r "{1}" VM  [inaktuell]\n
 
@@ -34,11 +34,12 @@
 java.launcher.ergo.message2  =\                  eftersom du k\u00F6r en serverklassmaskin.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <klass\u00F6kv\u00E4g till kataloger och zip-/jar-filer>\n    -classpath <klass\u00F6kv\u00E4g till kataloger och zip-/jar-filer>\n                  En {0}-avgr\u00E4nsad lista \u00F6ver kataloger, JAR-arkiv och\n                  ZIP-arkiv att s\u00F6ka efter klassfiler i.\n    -mp <moduls\u00F6kv\u00E4g>\n    -modulepath <moduls\u00F6kv\u00E4g>...\n                  En {0}-avgr\u00E4nsad lista \u00F6ver kataloger, d\u00E4r varje katalog\n                  \u00E4r en katalog med moduler.\n    -upgrademodulepath <moduls\u00F6kv\u00E4g>...\n                  En {0}-avgr\u00E4nsad lista \u00F6ver kataloger, d\u00E4r varje katalog\n                  \u00E4r en katalog med moduler som ers\u00E4tter uppgraderingsbara\n                  moduler i exekveringsavbilden \n    -m <modulnamn>[/<huvudklass>]\n                  den ursprungliga modulen att l\u00F6sa och namnet p\u00E5 huvudklassen\n                  att k\u00F6ra om den inte anges av modulen\n    -addmods <modulnamn>[,<modulnamn>...]\n                  rotmoduler att l\u00F6sa f\u00F6rutom den ursprungliga modulen\n    -limitmods <modulnamn>[,<modulnamn>...]\n                  begr\u00E4nsa universumet med observerbara moduler\n    -listmods[:<modulnamn>[,<modulnamn>...]]\n                  lista de observerbara modulerna och avsluta\n    --dry-run     skapa VM:en men k\u00F6r inte huvudmetoden.\n                  Det h\u00E4r alternativet kan vara anv\u00E4ndbart f\u00F6r att validera\n                  kommandoradsalternativen, som modulsystemkonfigurationen.\n    -D<name>=<v\u00E4rde>\n                  ange en systemvariabel\n    -verbose:[class|gc|jni]\n                  aktivera utf\u00F6rliga utdata\n    -version      skriv ut produktversion och avsluta\n    -showversion  skriv ut produktversion och forts\u00E4tt\n    -? -help      skriv ut det h\u00E4r hj\u00E4lpmeddelandet\n    -X            skriv ut hj\u00E4lp f\u00F6r icke-standardalternativ\n    -ea[:<paketnamn>...|:<klassnamn>]\n    -enableassertions[:<paketnamn>...|:<klassnamn>]\n                  aktivera verifieringar med den angivna detaljgraden\n    -da[:<paketnamn>...|:<klassnamn>]\n    -disableassertions[:<paketnamn>...|:<klassnamn>]\n                  avaktivera verifieringar med den angivna detaljgraden\n    -esa | -enablesystemassertions\n                  aktivera systemverifieringar\n    -dsa | -disablesystemassertions\n                  avaktivera systemverifieringar\n    -agentlib:<biblioteksnamn>[=<alternativ>]\n                  ladda det ursprungliga agentbiblioteket <biblioteksnamn>, exempel: -agentlib:jdwp\n                  se \u00E4ven -agentlib:jdwp=help\n    -agentpath:<s\u00F6kv\u00E4gsnamn>[=<alternativ>]\n                  ladda det ursprungliga agentbiblioteket med fullst\u00E4ndigt s\u00F6kv\u00E4gsnamn\n    -javaagent:<jar-s\u00F6kv\u00E4g>[=<alternativ>]\n                  ladda agenten f\u00F6r programmeringsspr\u00E5ket Java, se java.lang.instrument\n    -splash:<bilds\u00F6kv\u00E4g>\n                  visa v\u00E4lkomstsk\u00E4rmen med den angivna bilden\n    @<fils\u00F6kv\u00E4g>   l\u00E4s alternativ fr\u00E5n den angivna filen\n
+java.launcher.opt.footer     =\    -cp <klass\u00F6kv\u00E4g till kataloger och zip-/jar-filer>\n    -classpath <klass\u00F6kv\u00E4g till kataloger och zip-/jar-filer>\n    --class-path <klass\u00F6kv\u00E4g till kataloger och zip-/jar-filer>\n                  En lista \u00F6ver kataloger, JAR-arkiv och ZIP-arkiv att\n                  s\u00F6ka efter klassfiler i, avgr\u00E4nsad med {0}.\n    -p <moduls\u00F6kv\u00E4g>\n    --module-path <moduls\u00F6kv\u00E4g>...\n                  En lista \u00F6ver kataloger, d\u00E4r varje katalog \u00E4r en katalog\n                  med moduler, avgr\u00E4nsad med {0}.\n    --upgrade-module-path <moduls\u00F6kv\u00E4g>...\n                  En lista \u00F6ver kataloger, d\u00E4r varje katalog \u00E4r en katalog\n                  med moduler som ers\u00E4tter uppgraderingsbara moduler\n                  i exekveringsavbilden, avgr\u00E4nsad med {0} \n    -m <modul>[/<huvudklass>]\n    --module <modulnamn>[/<huvudklass>]\n                  den ursprungliga modulen att l\u00F6sa och namnet p\u00E5 huvudklassen\n                  att k\u00F6ra, om den inte anges av modulen\n    --add-modules <modulnamn>[,<modulnamn>...]\n                  rotmoduler att l\u00F6sa f\u00F6rutom den ursprungliga modulen.\n                  <modulnamn> kan \u00E4ven vara ALL-DEFAULT, ALL-SYSTEM och\n                  ALL-MODULE-PATH.\n    --limit-modules <modulnamn>[,<modulnamn>...]\n                  begr\u00E4nsa universumet med observerbara moduler\n    --list-modules [<modulnamn>[,<modulnamn>...]]\n                  lista de observerbara modulerna och avsluta\n    --dry-run     skapa VM:en men k\u00F6r inte huvudmetoden.\n                  Det h\u00E4r alternativet kan vara anv\u00E4ndbart f\u00F6r att validera\n                  kommandoradsalternativen, som modulsystemkonfigurationen.\n    -D<namn>=<v\u00E4rde>\n                  ange en systemegenskap\n    -verbose:[class|gc|jni]\n                  aktivera utf\u00F6rliga utdata\n    -version      skriv ut produktversion och avsluta\n    -showversion  skriv ut produktversion och forts\u00E4tt\n    -? -help --help\n                  skriv ut det h\u00E4r hj\u00E4lpmeddelandet\n    -X            skriv ut hj\u00E4lp f\u00F6r icke-standardalternativ\n    -ea[:<paketnamn>...|:<klassnamn>]\n    -enableassertions[:<paketnamn>...|:<klassnamn>]\n                  aktivera verifieringar med den angivna detaljgraden\n    -da[:<paketnamn>...|:<klassnamn>]\n    -disableassertions[:<paketnamn>...|:<klassnamn>]\n                  avaktivera verifieringar med den angivna detaljgraden\n    -esa | -enablesystemassertions\n                  aktivera systemverifieringar\n    -dsa | -disablesystemassertions\n                  avaktivera systemverifieringar\n    -agentlib:<biblioteksnamn>[=<alternativ>]\n                  ladda det ursprungliga agentbiblioteket <biblioteksnamn>, exempel: -agentlib:jdwp\n                  se \u00E4ven -agentlib:jdwp=help\n    -agentpath:<s\u00F6kv\u00E4gsnamn>[=<alternativ>]\n                  ladda det ursprungliga agentbiblioteket med fullst\u00E4ndigt s\u00F6kv\u00E4gsnamn\n    -javaagent:<jar-s\u00F6kv\u00E4g>[=<alternativ>]\n                  ladda agenten f\u00F6r programmeringsspr\u00E5ket Java, se java.lang.instrument\n    -splash:<bilds\u00F6kv\u00E4g>\n                  visa v\u00E4lkomstsk\u00E4rmen med den angivna bilden\n                  HiDPI-skal\u00E4ndrade bilder st\u00F6ds automatiskt och anv\u00E4nds om de \u00E4r\n                  tillg\u00E4ngliga. Filnamnet p\u00E5 den oskal\u00E4ndrade bilden, t.ex.\n                  bild.filtill\u00E4gg, ska alltid \u00F6verf\u00F6ras som argument till\n                  alternativet -splash.\n                  Den l\u00E4mpligaste skal\u00E4ndrade bilden v\u00E4ljs automatiskt.\n                  Mer information finns i dokumentationen f\u00F6r API:t SplashScreen.\n    @<fils\u00F6kv\u00E4g>   l\u00E4s alternativ fr\u00E5n den angivna filen\nOm du vill ange ett argument f\u00F6r \
+ett l\u00E5ngt alternativ kan du anv\u00E4nda --<namn>=<v\u00E4rde>\neller --<namn> <v\u00E4rde>.\n
 See Se http://www.oracle.com/technetwork/java/javase/documentation/index.html f\u00F6r mer information.
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           exekvering i blandat l\u00E4ge (standard)\n    -Xint             endast exekvering i tolkat l\u00E4ge\n    -Xbootclasspath/a:<kataloger och zip-/jar-filer avgr\u00E4nsade med {0}>\n                      l\u00E4gg till sist i klass\u00F6kv\u00E4gen f\u00F6r programladdning\n    -Xdiag            visa fler diagnostiska meddelanden\n    -Xdiag:resolver   visa diagnostiska meddelanden f\u00F6r matchning\n    -Xnoclassgc       avaktivera klasskr\u00E4pinsamling\n    -Xloggc:<fil>    logga GC-status till en fil med tidsst\u00E4mplar\n    -Xbatch           avaktivera bakgrundskompilering\n    -Xms<storlek>        ange ursprunglig storlek f\u00F6r Java-heap-utrymmet\n    -Xmx<storlek>        ange st\u00F6rsta storlek f\u00F6r Java-heap-utrymmet\n    -Xss<storlek>        ange storlek f\u00F6r java-tr\u00E5dsstacken\n    -Xprof            utdata f\u00F6r processorprofilering\n    -Xfuture          aktivera str\u00E4ngaste kontroller, f\u00F6rv\u00E4ntad framtida standard\n    -Xrs              minska operativsystemssignalanv\u00E4ndning f\u00F6r Java/VM (se dokumentationen)\n    -Xcheck:jni       utf\u00F6r fler kontroller f\u00F6r JNI-funktioner\n    -Xshare:off       f\u00F6rs\u00F6k inte anv\u00E4nda delade klassdata\n    -Xshare:auto      anv\u00E4nd delade klassdata om m\u00F6jligt (standard)\n    -Xshare:on        kr\u00E4v anv\u00E4ndning av delade klassdata, utf\u00F6r inte i annat fall.\n    -XshowSettings    visa alla inst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:all\n                      visa alla inst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:vm visa alla vm-relaterade inst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:properties\n                      visa alla egenskapsinst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:locale\n                      visa alla spr\u00E5kkonventionsrelaterade inst\u00E4llningar och forts\u00E4tt\n    -XaddReads:<modul>=<annan modul>(,<annan modul>)*\n                      <modul> l\u00E4ser andra moduler,\n                      oavsett moduldeklarationen\n    -XaddExports:<modul>/<paket>=<annan modul>(,<annan modul>)*\n                      <modul> exporterar <packet> till andra moduler,\n                      oavsett moduldeklarationen\n    -Xpatch:<modul>=<fil>({0}<fil>)*\n                      \u00C5sidos\u00E4tt eller ut\u00F6ka en modul med klasser och resurser\n                      i JAR-filer eller kataloger\n    -Xdisable-@files  avaktivera framtida argumentfilsut\u00F6kning\n\n-X-alternativen \u00E4r inte standard och kan \u00E4ndras utan f\u00F6reg\u00E5ende meddelande.\n
+java.launcher.X.usage=\    -Xbatch           avaktivera bakgrundskompilering\n    -Xbootclasspath/a:<kataloger och zip-/jar-filer avgr\u00E4nsade med {0}>\n                      l\u00E4gg till sist i klass\u00F6kv\u00E4gen f\u00F6r programladdning\n    -Xcheck:jni       utf\u00F6r fler kontroller f\u00F6r JNI-funktioner\n    -Xcomp            tvingar kompilering av metoder vid det f\u00F6rsta anropet\n    -Xdebug           tillhandah\u00E5lls f\u00F6r bak\u00E5tkompatibilitet\n    -Xdiag            visa fler diagnostiska meddelanden\n    -Xdiag:resolver   visa diagnostiska meddelanden f\u00F6r matchning\n    -Xdisable-@files  avaktivera ytterligare argumentfilsut\u00F6kning\n    -Xfuture          aktivera str\u00E4ngaste kontroller, f\u00F6rv\u00E4ntad framtida standard\n    -Xint             endast exekvering i tolkat l\u00E4ge\n    -Xinternalversion\n                      visar mer detaljerad information om JVM-version \u00E4n\n                      alternativet -version\n    -Xloggc:<fil>    logga GC-status till en fil med tidsst\u00E4mplar\n    -Xmixed           exekvering i blandat l\u00E4ge (standard)\n    -Xmn<storlek>     anger ursprunglig och maximal storlek (i byte) f\u00F6r h\u00F6gen f\u00F6r\n                      generationen med nyare objekt (h\u00F6gen f\u00F6r tilldelning av nya objekt)\n    -Xms<storlek>     ange ursprunglig storlek f\u00F6r Java-heap-utrymmet\n    -Xmx<storlek>     ange st\u00F6rsta storlek f\u00F6r Java-heap-utrymmet\n    -Xnoclassgc       avaktivera klasskr\u00E4pinsamling\n    -Xprof            utdata f\u00F6r processorprofilering\n    -Xrs              minska operativsystemssignalanv\u00E4ndning f\u00F6r Java/VM (se dokumentationen)\n    -Xshare:auto      anv\u00E4nd delade klassdata om m\u00F6jligt (standard)\n    -Xshare:off       f\u00F6rs\u00F6k inte anv\u00E4nda delade klassdata\n    -Xshare:on        kr\u00E4v anv\u00E4ndning av delade klassdata, utf\u00F6r inte i annat fall.\n    -XshowSettings    visa alla inst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:all\n                      visa alla inst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:locale\n                      visa alla spr\u00E5kkonventionsrelaterade inst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:properties\n                      visa alla egenskapsinst\u00E4llningar och forts\u00E4tt\n    -XshowSettings:vm visa alla vm-relaterade inst\u00E4llningar och forts\u00E4tt\n    -Xss<storlek>     ange storlek f\u00F6r java-tr\u00E5dsstacken\n    -Xverify          anger l\u00E4ge f\u00F6r bytekodverifieraren\n    --add-reads <modul>=<m\u00E5lmodul>(,<m\u00E5lmodul>)*\n                      uppdaterar <modul> att l\u00E4sa <m\u00E5lmodul>, oavsett\n                      moduldeklarationen. \n                      <m\u00E5lmodul> kan vara ALL-UNNAMED f\u00F6r att l\u00E4sa alla\n                      ej namngivna moduler.\n    --add-exports <modul>/<paket>=<m\u00E5lmodul>(,<m\u00E5lmodul>)*\n                      uppdaterar <modul> att exportera <paket> till <m\u00E5lmodul>,\n                      oavsett moduldeklarationen.\n                      <m\u00E5lmodul> kan vara ALL-UNNAMED f\u00F6r att exportera till alla\n                      ej namngivna moduler.\n    --patch-module <modul>=<fil>({0}<fil>)*\n                      \u00C5sidos\u00E4tt eller ut\u00F6ka en modul med klasser och resurser\n                      i JAR-filer eller kataloger.\n\nDe h\u00E4r alternativen \u00E4r icke-standardalternativ och kan \u00E4ndras utan f\u00F6reg\u00E5ende meddelande.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\nF\u00F6ljande alternativ \u00E4r Mac OS X-specifika:\n    -XstartOnFirstThread\n                      k\u00F6r main()-metoden p\u00E5 den f\u00F6rsta (AppKit)-tr\u00E5den\n    -Xdock:name=<applikationsnamn>\n                      \u00E5sidos\u00E4tt det standardapplikationsnamn som visas i dockan\n    -Xdock:icon=<s\u00F6kv\u00E4g till ikonfil>\n                      \u00E5sidos\u00E4tt den standardikon som visas i dockan\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   \u7528\u6CD5:  {0} [options] class [args...]\n           (\u6267\u884C\u7C7B)\n   \u6216  {0} [options] -jar jarfile [args...]\n           (\u6267\u884C jar \u6587\u4EF6)\n   \u6216  {0} [options] -mp <\u6A21\u5757\u8DEF\u5F84> -m <\u6A21\u5757\u540D\u79F0>[/<\u4E3B\u7C7B>] [args...]\n           (\u6267\u884C\u6A21\u5757\u4E2D\u7684\u4E3B\u7C7B)\n\u5176\u4E2D\u9009\u9879\u5305\u62EC:\n
+java.launcher.opt.header  =   \u7528\u6CD5: {0} [options] class [args...]\n           (\u6267\u884C\u7C7B)\n   \u6216  {0} [options] -jar jarfile [args...]\n           (\u6267\u884C jar \u6587\u4EF6)\n   \u6216  {0} [options] -p <\u6A21\u5757\u8DEF\u5F84> -m <\u6A21\u5757\u540D\u79F0>[/<\u6A21\u5757\u7C7B>] [args...]\n           (\u6267\u884C\u6A21\u5757\u4E2D\u7684\u4E3B\u7C7B)\n\u5176\u4E2D\u9009\u9879\u5305\u62EC:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  \u4F7F\u7528 {0} \u4F4D\u6570\u636E\u6A21\u578B (\u5982\u679C\u53EF\u7528)\n
+java.launcher.opt.datamodel  =\    -d{0}\t  \u5DF2\u8FC7\u65F6, \u5728\u4EE5\u540E\u7684\u53D1\u884C\u7248\u4E2D\u5C06\u88AB\u5220\u9664\n
 java.launcher.opt.vmselect   =\    {0}\t  \u9009\u62E9 "{1}" VM\n
 java.launcher.opt.hotspot    =\    {0}\t  \u662F "{1}" VM \u7684\u540C\u4E49\u8BCD [\u5DF2\u8FC7\u65F6]\n
 
@@ -34,12 +34,13 @@
 java.launcher.ergo.message2  =\                  \u56E0\u4E3A\u60A8\u662F\u5728\u670D\u52A1\u5668\u7C7B\u8BA1\u7B97\u673A\u4E0A\u8FD0\u884C\u3002\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <\u76EE\u5F55\u548C zip/jar \u6587\u4EF6\u7684\u7C7B\u641C\u7D22\u8DEF\u5F84>\n    -classpath <\u76EE\u5F55\u548C zip/jar \u6587\u4EF6\u7684\u7C7B\u641C\u7D22\u8DEF\u5F84>\n                  \u7528\u4E8E\u641C\u7D22\u7C7B\u6587\u4EF6\u7684\u76EE\u5F55, JAR \u6863\u6848\n                  \u548C ZIP \u6863\u6848\u7684\u5217\u8868, \u4F7F\u7528 {0} \u5206\u9694\u3002\n    -mp <\u6A21\u5757\u8DEF\u5F84>\n    -modulepath <\u6A21\u5757\u8DEF\u5F84>...\n                  \u7528 {0} \u5206\u9694\u7684\u76EE\u5F55\u5217\u8868, \u6BCF\u4E2A\u76EE\u5F55\n                  \u90FD\u662F\u4E00\u4E2A\u5305\u542B\u6A21\u5757\u7684\u76EE\u5F55\u3002\n    -upgrademodulepath <\u6A21\u5757\u8DEF\u5F84>...\n                  \u7528 {0} \u5206\u9694\u7684\u76EE\u5F55\u5217\u8868, \u6BCF\u4E2A\u76EE\u5F55\n                  \u90FD\u662F\u4E00\u4E2A\u5305\u542B\u6A21\u5757\u7684\u76EE\u5F55, \u8FD9\u4E9B\u6A21\u5757\n                  \u7528\u4E8E\u66FF\u6362\u8FD0\u884C\u65F6\u6620\u50CF\u4E2D\u7684\u53EF\u5347\u7EA7\u6A21\u5757\n    -m <\u6A21\u5757\u540D\u79F0>[/<\u4E3B\u7C7B>]\n                  \u8981\u89E3\u6790\u7684\u521D\u59CB\u6A21\u5757, \u4EE5\u53CA\u5728\u672A\u7531\u6A21\u5757\u6307\u5B9A\u65F6\n                  \u8981\u6267\u884C\u7684\u4E3B\u7C7B\u540D\u79F0\n    -addmods <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]\n                  \u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757\n    -limitmods <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]\n                  \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF\n    -listmods[:<\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]]\n                  \u5217\u51FA\u53EF\u89C2\u5BDF\u6A21\u5757\u5E76\u9000\u51FA\n    --dry-run     \u521B\u5EFA VM \u4F46\u4E0D\u6267\u884C\u4E3B\u65B9\u6CD5\u3002\n                  \u6B64 --dry-run \u9009\u9879\u5BF9\u4E8E\u9A8C\u8BC1\u8BF8\u5982\n                  \u6A21\u5757\u7CFB\u7EDF\u914D\u7F6E\u8FD9\u6837\u7684\u547D\u4EE4\u884C\u9009\u9879\u53EF\u80FD\u662F\u975E\u5E38\u6709\u7528\u7684\u3002\n    -D<\u540D\u79F0>=<\u503C>\n                  \u8BBE\u7F6E\u7CFB\u7EDF\u5C5E\u6027\n    -verbose:[class|gc|jni]\n                  \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n    -version      \u8F93\u51FA\u4EA7\u54C1\u7248\u672C\u5E76\u9000\u51FA\n    -showversion  \u8F93\u51FA\u4EA7\u54C1\u7248\u672C\u5E76\u7EE7\u7EED\n    -? -help      \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\n    -X            \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u5E2E\u52A9\n    -ea[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n    -enableassertions[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n                  \u6309\u6307\u5B9A\u7684\u7C92\u5EA6\u542F\u7528\u65AD\u8A00\n    -da[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7A0B\u5E8F\u5305\u540D\u79F0>]\n    -disableassertions[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n                  \u7981\u7528\u5177\u6709\u6307\u5B9A\u7C92\u5EA6\u7684\u65AD\u8A00\n    -esa | -enablesystemassertions\n                  \u542F\u7528\u7CFB\u7EDF\u65AD\u8A00\n    -dsa | -disablesystemassertions\n                  \u7981\u7528\u7CFB\u7EDF\u65AD\u8A00\n    -agentlib:<\u5E93\u540D>[=<\u9009\u9879>]\n                  \u52A0\u8F7D\u672C\u673A\u4EE3\u7406\u5E93 <\u5E93\u540D>, \u4F8B\u5982 -agentlib:jdwp\n                  \u53E6\u8BF7\u53C2\u9605 -agentlib:jdwp=help\n    -agentpath:<\u8DEF\u5F84\u540D>[=<\u9009\u9879>]\n                  \u6309\u5B8C\u6574\u8DEF\u5F84\u540D\u52A0\u8F7D\u672C\u673A\u4EE3\u7406\u5E93\n    -javaagent:<jar \u8DEF\u5F84>[=<\u9009\u9879>]\n                  \u52A0\u8F7D Java \u7F16\u7A0B\u8BED\u8A00\u4EE3\u7406, \u8BF7\u53C2\u9605 java.lang.instrument\n    -splash:<\u56FE\u50CF\u8DEF\u5F84>\n                  \u4F7F\u7528\u6307\u5B9A\u7684\u56FE\u50CF\u663E\u793A\u542F\u52A8\u5C4F\u5E55\n    @<\u6587\u4EF6\u8DEF\u5F84>   \
-\u4ECE\u6307\u5B9A\u6587\u4EF6\u4E2D\u8BFB\u53D6\u9009\u9879\n
+java.launcher.opt.footer     =\    -cp <\u76EE\u5F55\u548C zip/jar \u6587\u4EF6\u7684\u7C7B\u641C\u7D22\u8DEF\u5F84>\n    -classpath <\u76EE\u5F55\u548C zip/jar \u6587\u4EF6\u7684\u7C7B\u641C\u7D22\u8DEF\u5F84>\n    --class-path <\u76EE\u5F55\u548C zip/jar \u6587\u4EF6\u7684\u7C7B\u641C\u7D22\u8DEF\u5F84>\n                  \u7528\u4E8E\u641C\u7D22\u7C7B\u6587\u4EF6\u7684\u76EE\u5F55, JAR \u6863\u6848\n                  \u548C ZIP \u6863\u6848\u7684\u5217\u8868, \u4F7F\u7528 {0} \u5206\u9694\u3002\n    -p <\u6A21\u5757\u8DEF\u5F84>\n    --module-path <\u6A21\u5757\u8DEF\u5F84>...\n                  \u7528 {0} \u5206\u9694\u7684\u76EE\u5F55\u5217\u8868, \u6BCF\u4E2A\u76EE\u5F55\n                  \u90FD\u662F\u4E00\u4E2A\u5305\u542B\u6A21\u5757\u7684\u76EE\u5F55\u3002\n    --upgrade-module-path <\u6A21\u5757\u8DEF\u5F84>...\n                  \u7528 {0} \u5206\u9694\u7684\u76EE\u5F55\u5217\u8868, \u6BCF\u4E2A\u76EE\u5F55\n                  \u90FD\u662F\u4E00\u4E2A\u5305\u542B\u6A21\u5757\u7684\u76EE\u5F55, \u8FD9\u4E9B\u6A21\u5757\n                  \u7528\u4E8E\u66FF\u6362\u8FD0\u884C\u65F6\u6620\u50CF\u4E2D\u7684\u53EF\u5347\u7EA7\u6A21\u5757\n    -m <\u6A21\u5757>[/<\u4E3B\u7C7B>]\n    --module <\u6A21\u5757\u540D\u79F0>[/<\u4E3B\u7C7B>]\n                  \u8981\u89E3\u6790\u7684\u521D\u59CB\u6A21\u5757, \u4EE5\u53CA\u5728\u672A\u7531\u6A21\u5757\u6307\u5B9A\u65F6\n                  \u8981\u6267\u884C\u7684\u4E3B\u7C7B\u540D\u79F0\n    --add-modules <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]\n                  \u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757\u3002\n                  <\u6A21\u5757\u540D\u79F0> \u8FD8\u53EF\u4EE5\u4E3A ALL-DEFAULT, ALL-SYSTEM,\n                  ALL-MODULE-PATH\u3002\n    --limit-modules <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]\n                  \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF\n    --list-modules [<\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]]\n                  \u5217\u51FA\u53EF\u89C2\u5BDF\u6A21\u5757\u5E76\u9000\u51FA\n    --dry-run     \u521B\u5EFA VM \u4F46\u4E0D\u6267\u884C\u4E3B\u65B9\u6CD5\u3002\n                  \u6B64 --dry-run \u9009\u9879\u5BF9\u4E8E\u9A8C\u8BC1\u8BF8\u5982\n                  \u6A21\u5757\u7CFB\u7EDF\u914D\u7F6E\u8FD9\u6837\u7684\u547D\u4EE4\u884C\u9009\u9879\u53EF\u80FD\u662F\u975E\u5E38\u6709\u7528\u7684\u3002\n    -D<\u540D\u79F0>=<\u503C>\n                  \u8BBE\u7F6E\u7CFB\u7EDF\u5C5E\u6027\n    -verbose:[class|gc|jni]\n                  \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n    -version      \u8F93\u51FA\u4EA7\u54C1\u7248\u672C\u5E76\u9000\u51FA\n    -showversion  \u8F93\u51FA\u4EA7\u54C1\u7248\u672C\u5E76\u7EE7\u7EED\n    -? -help --help\n                  \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\n    -X            \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u5E2E\u52A9\n    -ea[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n    -enableassertions[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n                  \u6309\u6307\u5B9A\u7684\u7C92\u5EA6\u542F\u7528\u65AD\u8A00\n    -da[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n    -disableassertions[:<\u7A0B\u5E8F\u5305\u540D\u79F0>...|:<\u7C7B\u540D>]\n                  \u6309\u6307\u5B9A\u7684\u7C92\u5EA6\u7981\u7528\u65AD\u8A00\n    -esa | -enablesystemassertions\n                  \u542F\u7528\u7CFB\u7EDF\u65AD\u8A00\n    -dsa | -disablesystemassertions\n                  \u7981\u7528\u7CFB\u7EDF\u65AD\u8A00\n    -agentlib:<\u5E93\u540D>[=<\u9009\u9879>]\n                  \u52A0\u8F7D\u672C\u673A\u4EE3\u7406\u5E93 <\u5E93\u540D>, \u4F8B\u5982 -agentlib:jdwp\n                  \u53E6\u8BF7\u53C2\u9605 -agentlib:jdwp=help\n    -agentpath:<\u8DEF\u5F84\u540D>[=<\u9009\u9879>]\n                  \u6309\u5B8C\u6574\u8DEF\u5F84\u540D\u52A0\u8F7D\u672C\u673A\u4EE3\u7406\u5E93\n    -javaagent:<jar \u8DEF\u5F84>[=<\u9009\u9879>]\n                  \u52A0\u8F7D \
+Java \u7F16\u7A0B\u8BED\u8A00\u4EE3\u7406, \u8BF7\u53C2\u9605 java.lang.instrument\n    -splash:<\u56FE\u50CF\u8DEF\u5F84>\n                  \u4F7F\u7528\u6307\u5B9A\u7684\u56FE\u50CF\u663E\u793A\u542F\u52A8\u5C4F\u5E55\n                  \u81EA\u52A8\u652F\u6301\u548C\u4F7F\u7528 HiDPI \u7F29\u653E\u56FE\u50CF\n                  (\u5982\u679C\u53EF\u7528)\u3002\u672A\u7F29\u653E\u7684\u56FE\u50CF\u6587\u4EF6\u540D (\u4F8B\u5982, image.ext)\n                  \u5E94\u59CB\u7EC8\u4F5C\u4E3A\u53C2\u6570\u4F20\u9012\u7ED9 -splash \u9009\u9879\u3002\n                  \u5C06\u81EA\u52A8\u9009\u53D6\u63D0\u4F9B\u7684\u6700\u9002\u5F53\u7684\u7F29\u653E\n                  \u56FE\u50CF\u3002\n                  \u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u53C2\u9605 SplashScreen API \u6587\u6863\u3002\n    @<\u6587\u4EF6\u8DEF\u5F84>   \u4ECE\u6307\u5B9A\u6587\u4EF6\u4E2D\u8BFB\u53D6\u9009\u9879\n\u8981\u4E3A\u957F\u9009\u9879\u6307\u5B9A\u53C2\u6570, \u53EF\u4EE5\u4F7F\u7528 --<\u540D\u79F0>=<\u503C> \u6216\n--<\u540D\u79F0> <\u503C>\u3002\n
 See \u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u53C2\u9605 http://www.oracle.com/technetwork/java/javase/documentation/index.html\u3002
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           \u6DF7\u5408\u6A21\u5F0F\u6267\u884C (\u9ED8\u8BA4\u503C)\n    -Xint             \u4EC5\u89E3\u91CA\u6A21\u5F0F\u6267\u884C\n    -Xbootclasspath/a:<\u7528 {0} \u5206\u9694\u7684\u76EE\u5F55\u548C zip/jar \u6587\u4EF6>\n                      \u9644\u52A0\u5728\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u672B\u5C3E\n    -Xdiag            \u663E\u793A\u9644\u52A0\u8BCA\u65AD\u6D88\u606F\n    -Xdiag:resolver   \u663E\u793A\u89E3\u6790\u5668\u8BCA\u65AD\u6D88\u606F\n    -Xnoclassgc       \u7981\u7528\u7C7B\u5783\u573E\u6536\u96C6\n    -Xloggc:<\u6587\u4EF6>    \u5C06 GC \u72B6\u6001\u8BB0\u5F55\u5728\u6587\u4EF6\u4E2D (\u5E26\u65F6\u95F4\u6233)\n    -Xbatch           \u7981\u7528\u540E\u53F0\u7F16\u8BD1\n    -Xms<\u5927\u5C0F>        \u8BBE\u7F6E\u521D\u59CB Java \u5806\u5927\u5C0F\n    -Xmx<\u5927\u5C0F>        \u8BBE\u7F6E\u6700\u5927 Java \u5806\u5927\u5C0F\n    -Xss<\u5927\u5C0F>        \u8BBE\u7F6E Java \u7EBF\u7A0B\u5806\u6808\u5927\u5C0F\n    -Xprof            \u8F93\u51FA cpu \u5206\u6790\u6570\u636E\n    -Xfuture          \u542F\u7528\u6700\u4E25\u683C\u7684\u68C0\u67E5, \u9884\u671F\u5C06\u6765\u7684\u9ED8\u8BA4\u503C\n    -Xrs              \u51CF\u5C11 Java/VM \u5BF9\u64CD\u4F5C\u7CFB\u7EDF\u4FE1\u53F7\u7684\u4F7F\u7528 (\u8BF7\u53C2\u9605\u6587\u6863)\n    -Xcheck:jni       \u5BF9 JNI \u51FD\u6570\u6267\u884C\u5176\u4ED6\u68C0\u67E5\n    -Xshare:off       \u4E0D\u5C1D\u8BD5\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\n    -Xshare:auto      \u5728\u53EF\u80FD\u7684\u60C5\u51B5\u4E0B\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E (\u9ED8\u8BA4\u503C)\n    -Xshare:on        \u8981\u6C42\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E, \u5426\u5219\u5C06\u5931\u8D25\u3002\n    -XshowSettings    \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:all\n                      \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:vm \u663E\u793A\u6240\u6709\u4E0E vm \u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:properties\n                      \u663E\u793A\u6240\u6709\u5C5E\u6027\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:locale\n                      \u663E\u793A\u6240\u6709\u4E0E\u533A\u57DF\u8BBE\u7F6E\u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XaddReads:<\u6A21\u5757>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*\n                      <\u6A21\u5757> \u8BFB\u53D6\u5176\u4ED6\u6A21\u5757,\n                      \u800C\u65E0\u8BBA\u6A21\u5757\u58F0\u660E\u5982\u4F55\n    -XaddExports:<\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*\n                      <\u6A21\u5757> \u5C06 <\u7A0B\u5E8F\u5305> \u5BFC\u51FA\u5230\u5176\u4ED6\u6A21\u5757,\n                      \u800C\u65E0\u8BBA\u6A21\u5757\u58F0\u660E\u5982\u4F55\n    -Xpatch:<\u6A21\u5757>=<\u6587\u4EF6>({0}<\u6587\u4EF6>)*\n                      \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\n                      \u8986\u76D6\u6216\u589E\u5F3A\u6A21\u5757\n    -Xdisable-@files  \u7981\u6B62\u8FDB\u4E00\u6B65\u6269\u5C55\u53C2\u6570\u6587\u4EF6\n\n-X \u9009\u9879\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
+java.launcher.X.usage=\    -Xbatch           \u7981\u7528\u540E\u53F0\u7F16\u8BD1\n    -Xbootclasspath/a:<\u7528 {0} \u5206\u9694\u7684\u76EE\u5F55\u548C zip/jar \u6587\u4EF6>\n                      \u9644\u52A0\u5728\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u672B\u5C3E\n    -Xcheck:jni       \u5BF9 JNI \u51FD\u6570\u6267\u884C\u5176\u4ED6\u68C0\u67E5\n    -Xcomp            \u5728\u9996\u6B21\u8C03\u7528\u65F6\u5F3A\u5236\u7F16\u8BD1\u65B9\u6CD5\n    -Xdebug           \u4E3A\u5B9E\u73B0\u5411\u540E\u517C\u5BB9\u800C\u63D0\u4F9B\n    -Xdiag            \u663E\u793A\u9644\u52A0\u8BCA\u65AD\u6D88\u606F\n    -Xdiag:resolver   \u663E\u793A\u89E3\u6790\u5668\u8BCA\u65AD\u6D88\u606F\n    -Xdisable-@files  \u7981\u6B62\u8FDB\u4E00\u6B65\u6269\u5C55\u53C2\u6570\u6587\u4EF6\n    -Xfuture          \u542F\u7528\u6700\u4E25\u683C\u7684\u68C0\u67E5, \u9884\u671F\u5C06\u6765\u7684\u9ED8\u8BA4\u503C\n    -Xint             \u4EC5\u89E3\u91CA\u6A21\u5F0F\u6267\u884C\n    -Xinternalversion\n                      \u663E\u793A\u6BD4 -version \u9009\u9879\u66F4\u8BE6\u7EC6\u7684 JVM\n                      \u7248\u672C\u4FE1\u606F\n    -Xloggc:<\u6587\u4EF6>    \u5C06 GC \u72B6\u6001\u8BB0\u5F55\u5728\u6587\u4EF6\u4E2D (\u5E26\u65F6\u95F4\u6233)\n    -Xmixed           \u6DF7\u5408\u6A21\u5F0F\u6267\u884C (\u9ED8\u8BA4\u503C)\n    -Xmn<\u5927\u5C0F>        \u4E3A\u5E74\u8F7B\u4EE3 (\u65B0\u751F\u4EE3) \u8BBE\u7F6E\u521D\u59CB\u548C\u6700\u5927\u5806\u5927\u5C0F\n                      (\u4EE5\u5B57\u8282\u4E3A\u5355\u4F4D)\n    -Xms<\u5927\u5C0F>        \u8BBE\u7F6E\u521D\u59CB Java \u5806\u5927\u5C0F\n    -Xmx<\u5927\u5C0F>        \u8BBE\u7F6E\u6700\u5927 Java \u5806\u5927\u5C0F\n    -Xnoclassgc       \u7981\u7528\u7C7B\u5783\u573E\u6536\u96C6\n    -Xprof            \u8F93\u51FA cpu \u914D\u7F6E\u6587\u4EF6\u6570\u636E\n    -Xrs              \u51CF\u5C11 Java/VM \u5BF9\u64CD\u4F5C\u7CFB\u7EDF\u4FE1\u53F7\u7684\u4F7F\u7528 (\u8BF7\u53C2\u9605\u6587\u6863)\n    -Xshare:auto      \u5728\u53EF\u80FD\u7684\u60C5\u51B5\u4E0B\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E (\u9ED8\u8BA4\u503C)\n    -Xshare:off       \u4E0D\u5C1D\u8BD5\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E\n    -Xshare:on        \u8981\u6C42\u4F7F\u7528\u5171\u4EAB\u7C7B\u6570\u636E, \u5426\u5219\u5C06\u5931\u8D25\u3002\n    -XshowSettings    \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:all\n                      \u663E\u793A\u6240\u6709\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:locale\n                      \u663E\u793A\u6240\u6709\u4E0E\u533A\u57DF\u8BBE\u7F6E\u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EEDe\n    -XshowSettings:properties\n                      \u663E\u793A\u6240\u6709\u5C5E\u6027\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -XshowSettings:vm \u663E\u793A\u6240\u6709\u4E0E vm \u76F8\u5173\u7684\u8BBE\u7F6E\u5E76\u7EE7\u7EED\n    -Xss<\u5927\u5C0F>        \u8BBE\u7F6E Java \u7EBF\u7A0B\u5806\u6808\u5927\u5C0F\n    -Xverify          \u8BBE\u7F6E\u5B57\u8282\u7801\u9A8C\u8BC1\u5668\u7684\u6A21\u5F0F\n    --add-reads <\u6A21\u5757>=<\u76EE\u6807\u6A21\u5757>(,<\u76EE\u6807\u6A21\u5757>)*\n                      \u66F4\u65B0 <\u6A21\u5757> \u4EE5\u8BFB\u53D6 <\u76EE\u6807\u6A21\u5757>,\n                      \u800C\u65E0\u8BBA\u6A21\u5757\u58F0\u660E\u5982\u4F55\u3002\n                      <\u76EE\u6807\u6A21\u5757> \u53EF\u4EE5\u662F ALL-UNNAMED \u4EE5\u8BFB\u53D6\u6240\u6709\u672A\u547D\u540D\n                      \u6A21\u5757\u3002\n    --add-exports <\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u76EE\u6807\u6A21\u5757>(,<\u76EE\u6807\u6A21\u5757>)*\n                      \u66F4\u65B0 <\u6A21\u5757> \u4EE5\u5C06 <\u7A0B\u5E8F\u5305> \u5BFC\u51FA\u5230 <\u76EE\u6807\u6A21\u5757>,\n                      \u800C\u65E0\u8BBA\u6A21\u5757\u58F0\u660E\u5982\u4F55\u3002\n                      <\u76EE\u6807\u6A21\u5757> \u53EF\u4EE5\u662F ALL-UNNAMED \u4EE5\u5BFC\u51FA\u6240\u6709\n                      \u672A\u547D\u540D\u6A21\u5757\u3002\n    --patch-module \
+<\u6A21\u5757>=<\u6587\u4EF6>({0}<\u6587\u4EF6>)*\n                      \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\n                      \u8986\u76D6\u6216\u589E\u5F3A\u6A21\u5757\u3002\n\n\u8FD9\u4E9B\u9009\u9879\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\n\u4EE5\u4E0B\u9009\u9879\u4E3A Mac OS X \u7279\u5B9A\u7684\u9009\u9879:\n    -XstartOnFirstThread\n                      \u5728\u7B2C\u4E00\u4E2A (AppKit) \u7EBF\u7A0B\u4E0A\u8FD0\u884C main() \u65B9\u6CD5\n    -Xdock:name=<\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0>\n                      \u8986\u76D6\u505C\u9760\u680F\u4E2D\u663E\u793A\u7684\u9ED8\u8BA4\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0\n    -Xdock:icon=<\u56FE\u6807\u6587\u4EF6\u7684\u8DEF\u5F84>\n                      \u8986\u76D6\u505C\u9760\u680F\u4E2D\u663E\u793A\u7684\u9ED8\u8BA4\u56FE\u6807\n\n
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_zh_TW.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher_zh_TW.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2014, 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,9 +24,9 @@
 #
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.header  =   \u7528\u6CD5: {0} [options] class [args...]\n           (\u7528\u65BC\u57F7\u884C\u985E\u5225)\n   \u6216  {0} [options] -jar jarfile [args...]\n           (\u7528\u65BC\u57F7\u884C jar \u6A94\u6848)\n   \u6216  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (\u7528\u65BC\u57F7\u884C\u6A21\u7D44\u4E2D\u7684\u4E3B\u8981\u985E\u5225)\n\u5176\u4E2D\u7684\u9078\u9805\u5305\u62EC:\n
+java.launcher.opt.header  =   \u7528\u6CD5: {0} [options] class [args...]\n           (\u7528\u65BC\u57F7\u884C\u985E\u5225)\n   \u6216  {0} [options] -jar jarfile [args...]\n           (\u7528\u65BC\u57F7\u884C jar \u6A94\u6848)\n   \u6216  {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n           (\u7528\u65BC\u57F7\u884C\u6A21\u7D44\u4E2D\u7684\u4E3B\u8981\u985E\u5225)\n\u5176\u4E2D\u7684\u9078\u9805\u5305\u62EC:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  \u4F7F\u7528 {0} \u4F4D\u5143\u8CC7\u6599\u6A21\u578B (\u5982\u679C\u6709\u7684\u8A71)\n
+java.launcher.opt.datamodel  =\    -d{0}\t  \u5DF2\u4E0D\u518D\u4F7F\u7528\uFF0C\u5C07\u65BC\u672A\u4F86\u7248\u672C\u4E2D\u79FB\u9664\n
 java.launcher.opt.vmselect   =\    {0}\t  \u9078\u53D6 "{1}" VM\n
 java.launcher.opt.hotspot    =\    {0}\t  \u662F "{1}" VM \u7684\u540C\u7FA9\u5B57  [\u5DF2\u4E0D\u518D\u4F7F\u7528]\n
 
@@ -34,11 +34,13 @@
 java.launcher.ergo.message2  =\                  \u56E0\u70BA\u60A8\u6B63\u5728\u4F3A\u670D\u5668\u985E\u5225\u6A5F\u5668\u4E0A\u57F7\u884C\u3002\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\   -cp <\u76EE\u9304\u53CA zip/jar \u6A94\u6848\u7684\u985E\u5225\u641C\u5C0B\u8DEF\u5F91>\n    -classpath <\u76EE\u9304\u53CA zip/jar \u6A94\u6848\u7684\u985E\u5225\u641C\u5C0B\u8DEF\u5F91>\n                  \u5C07\u5728\u5176\u4E2D\u641C\u5C0B\u985E\u5225\u6A94\u6848\u4E4B\u4EE5 {0} \u5340\u9694\u7684\u76EE\u9304\u3001JAR \u5B58\u6A94\u4EE5\u53CA ZIP \u5B58\u6A94\u6E05\u55AE\u3002\n    -mp <module path>\n    -modulepath <module path>...\n                  \u4EE5 {0} \u5340\u9694\u7684\u76EE\u9304\u6E05\u55AE\uFF0C\u6BCF\u500B\u76EE\u9304\u90FD\u662F\u4E00\u500B\u6A21\u7D44\u76EE\u9304\u3002\n    -upgrademodulepath <module path>...\n                  \u4EE5 {0} \u5340\u9694\u7684\u76EE\u9304\u6E05\u55AE\uFF0C\u6BCF\u500B\u76EE\u9304\u90FD\u662F\u4E00\u500B\u6A21\u7D44\u76EE\u9304\uFF0C\u7576\u4E2D\u7684\u6A21\u7D44\u53EF\u53D6\u4EE3\u7A0B\u5F0F\u5BE6\u969B\u57F7\u884C\u5F71\u50CF\u4E2D\u7684\u53EF\u5347\u7D1A\u6A21\u7D44\n    -m <modulename>[/<mainclass>]\n                  \u8981\u89E3\u6790\u7684\u8D77\u59CB\u6A21\u7D44\uFF0C\u4EE5\u53CA\u6A21\u7D44\u672A\u6307\u5B9A\u6642\u6240\u8981\u57F7\u884C\u4E4B\u4E3B\u8981\u985E\u5225\u7684\u540D\u7A31\n    -addmods <modulename>[,<modulename>...]\n                  \u9664\u4E86\u8D77\u59CB\u6A21\u7D44\u5916\uFF0C\u8981\u89E3\u6790\u7684\u6839\u6A21\u7D44\n    -limitmods <modulename>[,<modulename>...]\n                  \u9650\u5236\u53EF\u76E3\u6E2C\u6A21\u7D44\u7684\u7BC4\u570D\n    -listmods[:<modulename>[,<modulename>...]]\n                  \u5217\u51FA\u53EF\u76E3\u6E2C\u6A21\u7D44\u4E26\u7D50\u675F\n    --dry-run     \u5EFA\u7ACB VM \u4F46\u4E0D\u57F7\u884C\u4E3B\u8981\u65B9\u6CD5\u3002\n                  \u6B64 --dry-run \u9078\u9805\u5C0D\u65BC\u9A57\u8B49\u547D\u4EE4\u884C\u9078\u9805 (\u4F8B\u5982\u6A21\u7D44\u7CFB\u7D71\u7D44\u614B) \u6703\u5F88\u6709\u7528\u3002\n    -D<name>=<value>\n                  \u8A2D\u5B9A\u7CFB\u7D71\u5C6C\u6027\n    -verbose:[class|gc|jni]\n                  \u555F\u7528\u8A73\u7D30\u8CC7\u8A0A\u8F38\u51FA\n    -version      \u5217\u5370\u7522\u54C1\u7248\u672C\u4E26\u7D50\u675F\n    -showversion  \u5217\u5370\u7522\u54C1\u7248\u672C\u4E26\u7E7C\u7E8C\n    -? -help      \u5217\u5370\u672C\u8AAA\u660E\u8A0A\u606F\n    -X            \u5217\u5370\u975E\u6A19\u6E96\u9078\u9805\u7684\u8AAA\u660E\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  \u555F\u7528\u6307\u5B9A\u4E4B\u8A73\u7D30\u7A0B\u5EA6\u7684\u5BA3\u544A\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  \u505C\u7528\u6307\u5B9A\u4E4B\u8A73\u7D30\u7A0B\u5EA6\u7684\u5BA3\u544A\n    -esa | -enablesystemassertions\n                  \u555F\u7528\u7CFB\u7D71\u5BA3\u544A\n    -dsa | -disablesystemassertions\n                  \u505C\u7528\u7CFB\u7D71\u5BA3\u544A\n    -agentlib:<libname>[=<options>]\n                  \u8F09\u5165\u539F\u751F\u4EE3\u7406\u7A0B\u5F0F\u7A0B\u5F0F\u5EAB <libname>\uFF0C\u4F8B\u5982 -agentlib:jdwp\n                  \u53E6\u8ACB\u53C3\u95B1 -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  \u4F7F\u7528\u5B8C\u6574\u8DEF\u5F91\u540D\u7A31\u8F09\u5165\u539F\u751F\u4EE3\u7406\u7A0B\u5F0F\u7A0B\u5F0F\u5EAB\n    -javaagent:<jarpath>[=<options>]\n                  \u8F09\u5165 Java \u7A0B\u5F0F\u8A9E\u8A00\u4EE3\u7406\u7A0B\u5F0F\uFF0C\u8ACB\u53C3\u95B1 java.lang.instrument\n    -splash:<imagepath>\n                  \u986F\u793A\u542B\u6307\u5B9A\u5F71\u50CF\u7684\u8EDF\u9AD4\u8CC7\u8A0A\u756B\u9762\n    @<filepath>   \u5F9E\u6307\u5B9A\u7684\u6A94\u6848\u8B80\u53D6\u9078\u9805\n
+java.launcher.opt.footer     =\    -cp <class search path of directories and zip/jar files>\n    -classpath <class search path of directories and zip/jar files>\n    --class-path <class search path of directories and zip/jar files>\n                  \u5C07\u5728\u5176\u4E2D\u641C\u5C0B\u985E\u5225\u6A94\u6848\u4E4B\u4EE5 {0} \u5340\u9694\u7684\n                  \u76EE\u9304\u3001JAR \u5B58\u6A94\u4EE5\u53CA ZIP \u5B58\u6A94\u6E05\u55AE\u3002\n    -p <module path>\n    --module-path <module path>...\n                  \u4EE5 {0} \u5340\u9694\u7684\u76EE\u9304\u6E05\u55AE\uFF0C\u6BCF\u500B\u76EE\u9304\n                  \u662F\u4E00\u500B\u6A21\u7D44\u76EE\u9304\u3002\n    --upgrade-module-path <module path>...\n                  \u4EE5 {0} \u5340\u9694\u7684\u76EE\u9304\u6E05\u55AE\uFF0C\u6BCF\u500B\u76EE\u9304\n                  \u90FD\u662F\u4E00\u500B\u6A21\u7D44\u76EE\u9304\uFF0C\u7576\u4E2D\u7684\u6A21\u7D44\u53EF\u53D6\u4EE3\n                  \u7A0B\u5F0F\u5BE6\u969B\u57F7\u884C\u5F71\u50CF\u4E2D\u7684\u53EF\u5347\u7D1A\u6A21\u7D44\n    -m <module>[/<mainclass>]\n    --module <modulename>[/<mainclass>]\n                  \u8981\u89E3\u6790\u7684\u8D77\u59CB\u6A21\u7D44\uFF0C\u4EE5\u53CA\u6A21\u7D44\u672A\u6307\u5B9A\u6642\n                  \u6240\u8981\u57F7\u884C\u4E4B\u4E3B\u8981\u985E\u5225\u7684\u540D\u7A31\n    --add-modules <modulename>[,<modulename>...]\n                  \u9664\u4E86\u8D77\u59CB\u6A21\u7D44\u5916\uFF0C\u8981\u89E3\u6790\u7684\u6839\u6A21\u7D44\u3002\n                  <modulename> \u4E5F\u53EF\u4EE5\u662F ALL-DEFAULT\u3001ALL-SYSTEM\u3001\n                  ALL-MODULE-PATH\u3002\n    --limit-modules <modulename>[,<modulename>...]\n                  \u9650\u5236\u53EF\u76E3\u6E2C\u6A21\u7D44\u7684\u7BC4\u570D\n    --list-modules [<modulename>[,<modulename>...]]\n                  \u5217\u51FA\u53EF\u76E3\u6E2C\u6A21\u7D44\u4E26\u7D50\u675F\n    --dry-run     \u5EFA\u7ACB VM \u4F46\u4E0D\u57F7\u884C\u4E3B\u8981\u65B9\u6CD5\u3002\n                  \u6B64 --dry-run \u9078\u9805\u5C0D\u65BC\u9A57\u8B49\u547D\u4EE4\u884C\u9078\u9805\n                  (\u4F8B\u5982\u6A21\u7D44\u7CFB\u7D71\u7D44\u614B) \u6703\u5F88\u6709\u7528\u3002\n    -D<name>=<value>\n                  \u8A2D\u5B9A\u7CFB\u7D71\u5C6C\u6027\n    -verbose:[class|gc|jni]\n                  \u555F\u7528\u8A73\u7D30\u8CC7\u8A0A\u8F38\u51FA\n    -version      \u5217\u5370\u7522\u54C1\u7248\u672C\u4E26\u7D50\u675F\n    -showversion  \u5217\u5370\u7522\u54C1\u7248\u672C\u4E26\u7E7C\u7E8C\n    -? -help --help\n                  \u5217\u5370\u672C\u8AAA\u660E\u8A0A\u606F\n    -X            \u5217\u5370\u975E\u6A19\u6E96\u9078\u9805\u7684\u8AAA\u660E\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  \u555F\u7528\u6307\u5B9A\u4E4B\u8A73\u7D30\u7A0B\u5EA6\u7684\u5BA3\u544A\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  \u505C\u7528\u6307\u5B9A\u4E4B\u8A73\u7D30\u7A0B\u5EA6\u7684\u5BA3\u544A\n    -esa | -enablesystemassertions\n                  \u555F\u7528\u7CFB\u7D71\u5BA3\u544A\n    -dsa | -disablesystemassertions\n                  \u505C\u7528\u7CFB\u7D71\u5BA3\u544A\n    -agentlib:<libname>[=<options>]\n                  \u8F09\u5165\u539F\u751F\u4EE3\u7406\u7A0B\u5F0F\u7A0B\u5F0F\u5EAB <libname>\uFF0C\u4F8B\u5982 -agentlib:jdwp\n                  \u53E6\u8ACB\u53C3\u95B1 -agentlib:jdwp=help\n    -agentpath:<pathname>[=<options>]\n                  \u4F7F\u7528\u5B8C\u6574\u8DEF\u5F91\u540D\u7A31\u8F09\u5165\u539F\u751F\u4EE3\u7406\u7A0B\u5F0F\u7A0B\u5F0F\u5EAB\n    -javaagent:<jarpath>[=<options>]\n                  \u8F09\u5165 Java \u7A0B\u5F0F\u8A9E\u8A00\u4EE3\u7406\u7A0B\u5F0F\uFF0C\u8ACB\u53C3\u95B1 java.lang.instrument\n    -splash:<imagepath>\n                  \u986F\u793A\u542B\u6307\u5B9A\u5F71\u50CF\u7684\u8EDF\u9AD4\u8CC7\u8A0A\u756B\u9762\n                  \
+\u7CFB\u7D71\u6703\u81EA\u52D5\u652F\u63F4\u4E26\u4F7F\u7528 HiDPI \u5DF2\u7E2E\u653E\u5F71\u50CF\n                  (\u5982\u679C\u53EF\u7528\u7684\u8A71)\u3002\u672A\u7E2E\u653E\u5F71\u50CF\u6A94\u6848\u540D\u7A31 (\u4F8B\u5982 image.ext)\n                  \u61C9\u4E00\u5F8B\u4EE5\u5F15\u6578\u7684\u5F62\u5F0F\u50B3\u9001\u5230 -splash \u9078\u9805\u3002\n                  \u7CFB\u7D71\u6703\u81EA\u52D5\u5F9E\u63D0\u4F9B\u7684\u5DF2\u7E2E\u653E\u5F71\u50CF\u4E2D\u9078\u64C7\u6700\u9069\u5408\u7684\n                  \u5DF2\u7E2E\u653E\u5F71\u50CF\u3002\n                  \u8ACB\u53C3\u95B1 SplashScreen API \u6587\u4EF6\uFF0C\u4EE5\u53D6\u5F97\u66F4\u591A\u8CC7\u8A0A\u3002\n    @<filepath>   \u5F9E\u6307\u5B9A\u7684\u6A94\u6848\u8B80\u53D6\u9078\u9805\n\u82E5\u8981\u6307\u5B9A\u9577\u9078\u9805\u7684\u5F15\u6578\uFF0C\u53EF\u4EE5\u4F7F\u7528 --<name>=<value> \u6216\n--<name> <value>\u3002\n
 See \u8ACB\u53C3\u95B1 http://www.oracle.com/technetwork/java/javase/documentation/index.html \u66B8\u89E3\u8A73\u7D30\u8CC7\u8A0A\u3002
 
 # Translators please note do not translate the options themselves
-java.launcher.X.usage=\    -Xmixed           \u6DF7\u5408\u6A21\u5F0F\u57F7\u884C (\u9810\u8A2D)\n    -Xint             \u50C5\u9650\u89E3\u8B6F\u6A21\u5F0F\u57F7\u884C\n    -Xbootclasspath/a:<\u4EE5 {0} \u5206\u9694\u7684\u76EE\u9304\u548C zip/jar \u6A94\u6848>\n                      \u9644\u52A0\u5728\u555F\u52D5\u5B89\u88DD\u985E\u5225\u8DEF\u5F91\u7684\u7D50\u5C3E\n    -Xdiag            \u986F\u793A\u5176\u4ED6\u7684\u8A3A\u65B7\u8A0A\u606F\n    -Xdiag:resolver   \u986F\u793A\u89E3\u6790\u5668\u8A3A\u65B7\u8A0A\u606F\n    -Xnoclassgc       \u505C\u7528\u985E\u5225\u8CC7\u6E90\u56DE\u6536\n    -Xloggc:<file>    \u5C07 GC \u72C0\u614B\u548C\u6642\u6233\u8A18\u9304\u81F3\u6A94\u6848\n    -Xbatch           \u505C\u7528\u80CC\u666F\u7DE8\u8B6F\n    -Xms<size>        \u8A2D\u5B9A\u8D77\u59CB Java \u5806\u96C6\u5927\u5C0F\n    -Xmx<size>        \u8A2D\u5B9A Java \u5806\u96C6\u5927\u5C0F\u4E0A\u9650\n    -Xss<size>        \u8A2D\u5B9A Java \u57F7\u884C\u7DD2\u5806\u758A\u5927\u5C0F\n    -Xprof            \u8F38\u51FA CPU \u5206\u6790\u8CC7\u6599\n    -Xfuture          \u555F\u7528\u6700\u56B4\u683C\u7684\u6AA2\u67E5\uFF0C\u9810\u5148\u4F5C\u70BA\u5C07\u4F86\u7684\u9810\u8A2D\n    -Xrs              \u6E1B\u5C11 Java/VM \u4F7F\u7528\u4F5C\u696D\u7CFB\u7D71\u4FE1\u865F (\u8ACB\u53C3\u95B1\u6587\u4EF6)\n    -Xcheck:jni       \u57F7\u884C\u5176\u4ED6\u7684 JNI \u51FD\u6578\u6AA2\u67E5\n    -Xshare:off       \u4E0D\u5617\u8A66\u4F7F\u7528\u5171\u7528\u985E\u5225\u8CC7\u6599\n    -Xshare:auto      \u5118\u53EF\u80FD\u4F7F\u7528\u5171\u7528\u985E\u5225\u8CC7\u6599 (\u9810\u8A2D)\n    -Xshare:on        \u9700\u8981\u4F7F\u7528\u5171\u7528\u985E\u5225\u8CC7\u6599\uFF0C\u5426\u5247\u5931\u6557\u3002\n    -XshowSettings    \u986F\u793A\u6240\u6709\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:all\n                      \u986F\u793A\u6240\u6709\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:vm \u986F\u793A\u6240\u6709 VM \u76F8\u95DC\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:properties\n                      \u986F\u793A\u6240\u6709\u5C6C\u6027\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:locale\n                      \u986F\u793A\u6240\u6709\u5730\u5340\u8A2D\u5B9A\u76F8\u95DC\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XaddReads:<module>=<other-module>(,<other-module>)*\n                      \u7121\u8AD6\u6A21\u7D44\u5BA3\u544A\u70BA\u4F55\uFF0C\n                      <module> \u6703\u8B80\u53D6\u5176\u4ED6\u6A21\u7D44\n    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                      \u7121\u8AD6\u6A21\u7D44\u5BA3\u544A\u70BA\u4F55\uFF0C<module> \u6703\u5C07 <package>\n                      \u532F\u51FA\u81F3\u5176\u4ED6\u6A21\u7D44\n    -Xpatch:<module>=<file>({0}<file>)*\n                      \u8986\u5BEB\u6216\u52A0\u5F37 JAR \u6A94\u6848\u6216\u76EE\u9304\u4E2D\u7684\n                      \u6A21\u7D44\u985E\u578B\u548C\u8CC7\u6E90\n    -Xdisable-@files  \u505C\u7528\u9032\u4E00\u6B65\u7684\u5F15\u6578\u6A94\u6848\u64F4\u5145\n\n-X  \u9078\u9805\u4E0D\u662F\u6A19\u6E96\u9078\u9805\uFF0C\u82E5\u6709\u8B8A\u66F4\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
+java.launcher.X.usage=\    -Xbatch           \u505C\u7528\u80CC\u666F\u7DE8\u8B6F\n    -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n                      \u52A0\u5728\u555F\u52D5\u5B89\u88DD\u985E\u5225\u8DEF\u5F91\u7684\u7D50\u5C3E\n    -Xcheck:jni       \u57F7\u884C\u5176\u4ED6\u7684 JNI \u51FD\u6578\u6AA2\u67E5\n    -Xcomp            \u5F37\u5236\u7DE8\u8B6F\u7B2C\u4E00\u500B\u547C\u53EB\u7684\u65B9\u6CD5\n    -Xdebug           \u70BA\u56DE\u6EAF\u76F8\u5BB9\u6027\u63D0\u4F9B\n    -Xdiag            \u986F\u793A\u5176\u4ED6\u8A3A\u65B7\u8A0A\u606F\n    -Xdiag:resolver   \u986F\u793A\u89E3\u6790\u5668\u8A3A\u65B7\u8A0A\u606F\n    -Xdisable-@files  \u505C\u7528\u9032\u4E00\u6B65\u7684\u5F15\u6578\u6A94\u6848\u64F4\u5145\n    -Xfuture          \u555F\u7528\u6700\u56B4\u683C\u7684\u6AA2\u67E5\uFF0C\u9810\u5148\u4F5C\u70BA\u5C07\u4F86\u7684\u9810\u8A2D\n    -Xint             \u50C5\u9650\u89E3\u8B6F\u6A21\u5F0F\u57F7\u884C\n    -Xinternalversion\n                      \u986F\u793A\u6BD4\u4F7F\u7528 -version \u9078\u9805\u6642\u66F4\u70BA\u8A73\u7D30\u7684\n                      JVM \u7248\u672C\u8CC7\u8A0A\n    -Xloggc:<file>    \u5C07 GC \u72C0\u614B\u548C\u6642\u6233\u8A18\u9304\u81F3\u6A94\u6848\n    -Xmixed           \u6DF7\u5408\u6A21\u5F0F\u57F7\u884C (\u9810\u8A2D)\n    -Xmn<size>        \u91DD\u5C0D\u65B0\u751F\u4EE3 (\u990A\u6210\u5340) \u8A2D\u5B9A\u5806\u96C6\u7684\u8D77\u59CB\u5927\u5C0F\u548C\n                      \u5927\u5C0F\u4E0A\u9650 (\u4F4D\u5143\u7D44)\n    -Xms<size>        \u8A2D\u5B9A\u8D77\u59CB Java \u5806\u96C6\u5927\u5C0F\n    -Xmx<size>        \u8A2D\u5B9A Java \u5806\u96C6\u5927\u5C0F\u4E0A\u9650\n    -Xnoclassgc       \u505C\u7528\u985E\u5225\u8CC7\u6E90\u56DE\u6536\n    -Xprof            \u8F38\u51FA cpu \u5206\u6790\u8CC7\u6599\n    -Xrs              \u6E1B\u5C11 Java/VM \u4F7F\u7528\u4F5C\u696D\u7CFB\u7D71\u4FE1\u865F (\u8ACB\u53C3\u95B1\u6587\u4EF6)\n    -Xshare:auto      \u76E1\u53EF\u80FD\u4F7F\u7528\u5171\u7528\u985E\u5225\u8CC7\u6599 (\u9810\u8A2D)\n    -Xshare:off       \u4E0D\u5617\u8A66\u4F7F\u7528\u5171\u7528\u985E\u5225\u8CC7\u6599\n    -Xshare:on        \u9700\u8981\u4F7F\u7528\u5171\u7528\u985E\u5225\u8CC7\u6599\uFF0C\u5426\u5247\u5931\u6557\u3002\n    -XshowSettings    \u986F\u793A\u6240\u6709\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:all\n                      \u986F\u793A\u6240\u6709\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:locale\n                      \u986F\u793A\u6240\u6709\u5730\u5340\u8A2D\u5B9A\u76F8\u95DC\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:properties\n                      \u986F\u793A\u6240\u6709\u5C6C\u6027\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -XshowSettings:vm \u986F\u793A\u6240\u6709 VM \u76F8\u95DC\u8A2D\u5B9A\u503C\u4E26\u7E7C\u7E8C\n    -Xss<size>        \u8A2D\u5B9A Java \u57F7\u884C\u7DD2\u5806\u758A\u5927\u5C0F\n    -Xverify          \u8A2D\u5B9A Bytecode \u9A57\u8B49\u7A0B\u5F0F\u6A21\u5F0F\n    --add-reads <module>=<target-module>(,<target-module>)*\n                      \u7121\u8AD6\u6A21\u7D44\u5BA3\u544A\u70BA\u4F55\uFF0C\u66F4\u65B0 <module> \u4EE5\n                      \u8B80\u53D6 <target-module>\u3002\n                      \u53EF\u5C07 <target-module> \u8A2D\u70BA ALL-UNNAMED \u4EE5\u8B80\u53D6\u6240\u6709\u672A\u547D\u540D\u7684\n                      \u6A21\u7D44\u3002\n    --add-exports <module>/<package>=<target-module>(,<target-module>)*\n                      \u7121\u8AD6\u6A21\u7D44\u5BA3\u544A\u70BA\u4F55\uFF0C\u66F4\u65B0 <module> \u4EE5\u4FBF\u5C07 <package>\n                      \u532F\u51FA\u81F3 <target-module>\u3002\n                      \u53EF\u5C07 <target-module> \u8A2D\u70BA ALL-UNNAMED \u4EE5\u532F\u51FA\u81F3\u6240\u6709\n                      \u672A\u547D\u540D\u7684\u6A21\u7D44\u3002\n    --patch-module <module>=<file>({0}<file>)*\n                      \u8986\u5BEB\u6216\u52A0\u5F37 JAR \u6A94\u6848\u6216\u76EE\u9304\u4E2D\n                      \
+\u542B\u6709\u985E\u5225\u548C\u8CC7\u6E90\u7684\u6A21\u7D44\u3002\n\n\u4E0A\u8FF0\u9078\u9805\u4E0D\u662F\u6A19\u6E96\u9078\u9805\uFF0C\u82E5\u6709\u8B8A\u66F4\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\n\u4E0B\u5217\u662F Mac OS X \u7279\u5B9A\u9078\u9805:\n    -XstartOnFirstThread\n                      \u5728\u7B2C\u4E00\u500B (AppKit) \u57F7\u884C\u7DD2\u57F7\u884C main() \u65B9\u6CD5\n    -Xdock:name=<application name>\n                      \u8986\u5BEB\u7D50\u5408\u8AAA\u660E\u756B\u9762\u4E2D\u986F\u793A\u7684\u9810\u8A2D\u61C9\u7528\u7A0B\u5F0F\u540D\u7A31\n    -Xdock:icon=<path to icon file>\n                      \u8986\u5BEB\u7D50\u5408\u8AAA\u660E\u756B\u9762\u4E2D\u986F\u793A\u7684\u9810\u8A2D\u5716\u793A\n\n
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -898,57 +898,62 @@
             if (!isOpen())
                 return null;
 
-            long filesize;
-            do {
-                filesize = nd.size(fd);
-            } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
-            if (!isOpen())
-                return null;
-
-            if (filesize < position + size) { // Extend file size
-                if (!writable) {
-                    throw new IOException("Channel not open for writing " +
-                        "- cannot extend file to required size");
-                }
-                int rv;
+            long mapSize;
+            int pagePosition;
+            synchronized (positionLock) {
+                long filesize;
                 do {
-                    rv = nd.truncate(fd, position + size);
-                } while ((rv == IOStatus.INTERRUPTED) && isOpen());
+                    filesize = nd.size(fd);
+                } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
                 if (!isOpen())
                     return null;
-            }
-            if (size == 0) {
-                addr = 0;
-                // a valid file descriptor is not required
-                FileDescriptor dummy = new FileDescriptor();
-                if ((!writable) || (imode == MAP_RO))
-                    return Util.newMappedByteBufferR(0, 0, dummy, null);
-                else
-                    return Util.newMappedByteBuffer(0, 0, dummy, null);
-            }
+
+                if (filesize < position + size) { // Extend file size
+                    if (!writable) {
+                        throw new IOException("Channel not open for writing " +
+                            "- cannot extend file to required size");
+                    }
+                    int rv;
+                    do {
+                        rv = nd.allocate(fd, position + size);
+                    } while ((rv == IOStatus.INTERRUPTED) && isOpen());
+                    if (!isOpen())
+                        return null;
+                }
+
+                if (size == 0) {
+                    addr = 0;
+                    // a valid file descriptor is not required
+                    FileDescriptor dummy = new FileDescriptor();
+                    if ((!writable) || (imode == MAP_RO))
+                        return Util.newMappedByteBufferR(0, 0, dummy, null);
+                    else
+                        return Util.newMappedByteBuffer(0, 0, dummy, null);
+                }
 
-            int pagePosition = (int)(position % allocationGranularity);
-            long mapPosition = position - pagePosition;
-            long mapSize = size + pagePosition;
-            try {
-                // If no exception was thrown from map0, the address is valid
-                addr = map0(imode, mapPosition, mapSize);
-            } catch (OutOfMemoryError x) {
-                // An OutOfMemoryError may indicate that we've exhausted memory
-                // so force gc and re-attempt map
-                System.gc();
+                pagePosition = (int)(position % allocationGranularity);
+                long mapPosition = position - pagePosition;
+                mapSize = size + pagePosition;
                 try {
-                    Thread.sleep(100);
-                } catch (InterruptedException y) {
-                    Thread.currentThread().interrupt();
-                }
-                try {
+                    // If map0 did not throw an exception, the address is valid
                     addr = map0(imode, mapPosition, mapSize);
-                } catch (OutOfMemoryError y) {
-                    // After a second OOME, fail
-                    throw new IOException("Map failed", y);
+                } catch (OutOfMemoryError x) {
+                    // An OutOfMemoryError may indicate that we've exhausted
+                    // memory so force gc and re-attempt map
+                    System.gc();
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException y) {
+                        Thread.currentThread().interrupt();
+                    }
+                    try {
+                        addr = map0(imode, mapPosition, mapSize);
+                    } catch (OutOfMemoryError y) {
+                        // After a second OOME, fail
+                        throw new IOException("Map failed", y);
+                    }
                 }
-            }
+            } // synchronized
 
             // On Windows, and potentially other platforms, we need an open
             // file descriptor for some mapping operations.
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileDispatcher.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileDispatcher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, 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
@@ -40,6 +40,8 @@
 
     abstract int truncate(FileDescriptor fd, long size) throws IOException;
 
+    abstract int allocate(FileDescriptor fd, long size) throws IOException;
+
     abstract long size(FileDescriptor fd) throws IOException;
 
     abstract int lock(FileDescriptor fd, boolean blocking, long pos, long size,
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_de.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_de.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "Schl\u00FCsselbitgr\u00F6\u00DFe"}, //-keysize
         {"keystore.name",
                 "Keystore-Name"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "Zugriff auf den cacerts Keystore"}, // -cacerts
+        {"warning.cacerts.option",
+                "Warnung: Verwenden Sie die Option -cacerts f\u00FCr den Zugriff auf den cacerts Keystore"},
         {"new.password",
                 "Neues Kennwort"}, //-new
         {"do.not.prompt",
                 "Kein Prompt"}, //-noprompt
         {"password.through.protected.mechanism",
                 "Kennwort \u00FCber gesch\u00FCtzten Mechanismus"}, //-protected
-        {"provider.argument",
-                "Providerargument"}, //-providerarg
-        {"provider.class.name",
-                "Providerklassenname"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "Sicherheitsprovider nach Name hinzuf\u00FCgen (z.B. SunPKCS11)\nArgument f\u00FCr -addprovider konfigurieren"}, //-addprovider
+        {"provider.class.option",
+                "Sicherheitsprovider nach vollst\u00E4ndig angegebenem Klassennamen hinzuf\u00FCgen\nArgument f\u00FCr -providerclass konfigurieren"}, //-providerclass
+
         {"provider.name",
                 "Providername"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "Befehlsoption {0} ben\u00F6tigt ein Argument."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Warnung: Keine Unterst\u00FCtzung f\u00FCr unterschiedliche Speicher- und Schl\u00FCsselkennw\u00F6rter bei PKCS12 KeyStores. Der benutzerdefinierte Wert {0} wird ignoriert."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "Die Option -keystore oder -storetype kann nicht mit der Option -cacerts verwendet werden"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-keystore muss NONE sein, wenn -storetype {0} ist"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "Ung\u00FCltiger Wert f\u00FCr Anfangsdatum"},
         {"Validity.must.be.greater.than.zero",
                 "G\u00FCltigkeit muss gr\u00F6\u00DFer als null sein"},
-        {"provName.not.a.provider", "{0} kein Provider"},
+        {"provclass.not.a.provider", "%s kein Provider"},
+        {"provider.name.not.found", "Provider namens \"%s\" nicht gefunden"},
+        {"provider.class.not.found", "Provider \"%s\" nicht gefunden"},
         {"Usage.error.no.command.provided", "Verwendungsfehler: Kein Befehl angegeben"},
         {"Source.keystore.file.exists.but.is.empty.", "Quell-Keystore-Datei ist zwar vorhanden, ist aber leer: "},
         {"Please.specify.srckeystore", "Geben Sie -srckeystore an"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_es.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_es.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "tama\u00F1o de bit de clave"}, //-keysize
         {"keystore.name",
                 "nombre de almac\u00E9n de claves"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "acceso al almac\u00E9n de claves cacerts"}, // -cacerts
+        {"warning.cacerts.option",
+                "Advertencia: Utilice la opci\u00F3n -cacerts para acceder al almac\u00E9n de claves cacerts"},
         {"new.password",
                 "nueva contrase\u00F1a"}, //-new
         {"do.not.prompt",
                 "no solicitar"}, //-noprompt
         {"password.through.protected.mechanism",
                 "contrase\u00F1a a trav\u00E9s de mecanismo protegido"}, //-protected
-        {"provider.argument",
-                "argumento del proveedor"}, //-providerarg
-        {"provider.class.name",
-                "nombre de clase del proveedor"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "agregar proveedor de seguridad por nombre (por ejemplo, SunPKCS11)\nconfigurar elemento para -addprovider"}, //-addprovider
+        {"provider.class.option",
+                "agregar proveedor de seguridad por nombre de clase totalmente cualificado\nconfigurar argumento para -providerclass"}, //-providerclass
+
         {"provider.name",
                 "nombre del proveedor"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "La opci\u00F3n de comando {0} necesita un argumento."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Advertencia: los almacenes de claves en formato PKCS12 no admiten contrase\u00F1as de clave y almacenamiento distintas. Se ignorar\u00E1 el valor especificado por el usuario, {0}."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "Las opciones -keystore o -storetype no se pueden utilizar con la opci\u00F3n -cacerts"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-keystore debe ser NONE si -storetype es {0}"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "Valor de fecha de inicio no permitido"},
         {"Validity.must.be.greater.than.zero",
                 "La validez debe ser mayor que cero"},
-        {"provName.not.a.provider", "{0} no es un proveedor"},
+        {"provclass.not.a.provider", "%s no es un proveedor"},
+        {"provider.name.not.found", "No se ha encontrado el proveedor denominado \"%s\""},
+        {"provider.class.not.found", "No se ha encontrado el proveedor \"%s\""},
         {"Usage.error.no.command.provided", "Error de sintaxis: no se ha proporcionado ning\u00FAn comando"},
         {"Source.keystore.file.exists.but.is.empty.", "El archivo de almac\u00E9n de claves de origen existe, pero est\u00E1 vac\u00EDo: "},
         {"Please.specify.srckeystore", "Especifique -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_fr.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_fr.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "taille en bits de la cl\u00E9"}, //-keysize
         {"keystore.name",
                 "nom du fichier de cl\u00E9s"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "acc\u00E9der au fichier de cl\u00E9s cacerts"}, // -cacerts
+        {"warning.cacerts.option",
+                "Avertissement : utiliser l'option -cacerts pour acc\u00E9der au fichier de cl\u00E9s cacerts"},
         {"new.password",
                 "nouveau mot de passe"}, //-new
         {"do.not.prompt",
                 "ne pas inviter"}, //-noprompt
         {"password.through.protected.mechanism",
                 "mot de passe via m\u00E9canisme prot\u00E9g\u00E9"}, //-protected
-        {"provider.argument",
-                "argument du fournisseur"}, //-providerarg
-        {"provider.class.name",
-                "nom de la classe de fournisseur"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "ajouter un fournisseur de s\u00E9curit\u00E9 par nom (par ex. SunPKCS11)\nconfigurer l'argument pour -addprovider"}, //-addprovider
+        {"provider.class.option",
+                "ajouter un fournisseur de s\u00E9curit\u00E9 par nom de classe qualifi\u00E9 complet\nconfigurer l'argument pour -providerclass"}, //-providerclass
+
         {"provider.name",
                 "nom du fournisseur"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "L''option de commande {0} requiert un argument."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Avertissement\u00A0: les mots de passe de cl\u00E9 et de banque distincts ne sont pas pris en charge pour les fichiers de cl\u00E9s d''acc\u00E8s PKCS12. La valeur {0} sp\u00E9cifi\u00E9e par l''utilisateur est ignor\u00E9e."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "Les options -keystore ou -storetype ne peuvent pas \u00EAtre utilis\u00E9es avec l'option -cacerts"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-keystore doit \u00EAtre d\u00E9fini sur NONE si -storetype est {0}"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "Valeur de date de d\u00E9but non admise"},
         {"Validity.must.be.greater.than.zero",
                 "La validit\u00E9 doit \u00EAtre sup\u00E9rieure \u00E0 z\u00E9ro"},
-        {"provName.not.a.provider", "{0} n''est pas un fournisseur"},
+        {"provclass.not.a.provider", "%s n'est pas un fournisseur"},
+        {"provider.name.not.found", "Fournisseur nomm\u00E9 \"%s\" introuvable"},
+        {"provider.class.not.found", "Fournisseur \"%s\" introuvable"},
         {"Usage.error.no.command.provided", "Erreur de syntaxe\u00A0: aucune commande fournie"},
         {"Source.keystore.file.exists.but.is.empty.", "Le fichier de cl\u00E9s source existe mais il est vide : "},
         {"Please.specify.srckeystore", "Indiquez -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_it.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_it.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "dimensione bit chiave"}, //-keysize
         {"keystore.name",
                 "nome keystore"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "accedi al keystore cacerts"}, // -cacerts
+        {"warning.cacerts.option",
+                "Avvertenza: utilizzare l'opzione -cacerts per accedere al keystore cacerts"},
         {"new.password",
                 "nuova password"}, //-new
         {"do.not.prompt",
                 "non richiedere"}, //-noprompt
         {"password.through.protected.mechanism",
                 "password mediante meccanismo protetto"}, //-protected
-        {"provider.argument",
-                "argomento provider"}, //-providerarg
-        {"provider.class.name",
-                "nome classe provider"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "aggiunge il provider di sicurezza in base al nome (ad esempio SunPKCS11)\nconfigura l'argomento per -addprovider"}, //-addprovider
+        {"provider.class.option",
+                "aggiunge il provider di sicurezza in base al nome di classe completamente qualificato\nconfigura l'argomento per -providerclass"}, //-providerclass
+
         {"provider.name",
                 "nome provider"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "\u00C8 necessario specificare un argomento per l''opzione di comando {0}."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Avvertenza: non sono supportate password diverse di chiave e di archivio per i keystore PKCS12. Il valore {0} specificato dall''utente verr\u00E0 ignorato."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "L'opzione -keystore o -storetype non pu\u00F2 essere utilizzata con l'opzione -cacerts"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "Se -storetype \u00E8 impostato su {0}, -keystore deve essere impostato su NONE"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "Valore di data di inizio non valido"},
         {"Validity.must.be.greater.than.zero",
                 "La validit\u00E0 deve essere maggiore di zero"},
-        {"provName.not.a.provider", "{0} non \u00E8 un provider"},
+        {"provclass.not.a.provider", "%s non \u00E8 un provider"},
+        {"provider.name.not.found", "Provider denominato \"%s\" non trovato"},
+        {"provider.class.not.found", "Provider \"%s\" non trovato"},
         {"Usage.error.no.command.provided", "Errore di utilizzo: nessun comando specificato"},
         {"Source.keystore.file.exists.but.is.empty.", "Il file keystore di origine esiste, ma \u00E8 vuoto: "},
         {"Please.specify.srckeystore", "Specificare -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "\u9375\u306E\u30D3\u30C3\u30C8\u30FB\u30B5\u30A4\u30BA"}, //-keysize
         {"keystore.name",
                 "\u30AD\u30FC\u30B9\u30C8\u30A2\u540D"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "cacerts\u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B"}, // -cacerts
+        {"warning.cacerts.option",
+                "\u8B66\u544A: cacerts\u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u306B\u306F-cacerts\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044"},
         {"new.password",
                 "\u65B0\u898F\u30D1\u30B9\u30EF\u30FC\u30C9"}, //-new
         {"do.not.prompt",
                 "\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8868\u793A\u3057\u306A\u3044"}, //-noprompt
         {"password.through.protected.mechanism",
                 "\u4FDD\u8B77\u30E1\u30AB\u30CB\u30BA\u30E0\u306B\u3088\u308B\u30D1\u30B9\u30EF\u30FC\u30C9"}, //-protected
-        {"provider.argument",
-                "\u30D7\u30ED\u30D0\u30A4\u30C0\u5F15\u6570"}, //-providerarg
-        {"provider.class.name",
-                "\u30D7\u30ED\u30D0\u30A4\u30C0\u30FB\u30AF\u30E9\u30B9\u540D"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "\u540D\u524D\u3067\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u3092\u8FFD\u52A0\u3059\u308B(SunPKCS11\u306A\u3069)\n-addprovider\u306E\u5F15\u6570\u3092\u69CB\u6210\u3059\u308B"}, //-addprovider
+        {"provider.class.option",
+                "\u5B8C\u5168\u4FEE\u98FE\u30AF\u30E9\u30B9\u540D\u3067\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u3092\u8FFD\u52A0\u3059\u308B\n-providerclass\u306E\u5F15\u6570\u3092\u69CB\u6210\u3059\u308B"}, //-providerclass
+
         {"provider.name",
                 "\u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "\u30B3\u30DE\u30F3\u30C9\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3059\u3002"},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "\u8B66\u544A: PKCS12\u30AD\u30FC\u30B9\u30C8\u30A2\u3067\u306F\u3001\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u3068\u9375\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u7570\u306A\u308B\u72B6\u6CC1\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u307E\u305B\u3093\u3002\u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F{0}\u306E\u5024\u306F\u7121\u8996\u3057\u307E\u3059\u3002"},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "-keystore\u307E\u305F\u306F-storetype\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u3001-cacerts\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u3068\u3082\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-storetype\u304C{0}\u306E\u5834\u5408\u3001-keystore\u306FNONE\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "startdate\u5024\u304C\u7121\u52B9\u3067\u3059"},
         {"Validity.must.be.greater.than.zero",
                 "\u59A5\u5F53\u6027\u306F\u30BC\u30ED\u3088\u308A\u5927\u304D\u3044\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
-        {"provName.not.a.provider", "{0}\u306F\u30D7\u30ED\u30D0\u30A4\u30C0\u3067\u306F\u3042\u308A\u307E\u305B\u3093"},
+        {"provclass.not.a.provider", "%s\u306F\u30D7\u30ED\u30D0\u30A4\u30C0\u3067\u306F\u3042\u308A\u307E\u305B\u3093"},
+        {"provider.name.not.found", "\u30D7\u30ED\u30D0\u30A4\u30C0\u540D\"%s\"\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
+        {"provider.class.not.found", "\u30D7\u30ED\u30D0\u30A4\u30C0\"%s\"\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
         {"Usage.error.no.command.provided", "\u4F7F\u7528\u30A8\u30E9\u30FC: \u30B3\u30DE\u30F3\u30C9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093"},
         {"Source.keystore.file.exists.but.is.empty.", "\u30BD\u30FC\u30B9\u30FB\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u306F\u3001\u5B58\u5728\u3057\u307E\u3059\u304C\u7A7A\u3067\u3059: "},
         {"Please.specify.srckeystore", "-srckeystore\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_ko.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_ko.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "\uD0A4 \uBE44\uD2B8 \uD06C\uAE30"}, //-keysize
         {"keystore.name",
                 "\uD0A4 \uC800\uC7A5\uC18C \uC774\uB984"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "cacerts \uD0A4 \uC800\uC7A5\uC18C \uC561\uC138\uC2A4"}, // -cacerts
+        {"warning.cacerts.option",
+                "\uACBD\uACE0: -cacerts \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC5EC cacerts \uD0A4 \uC800\uC7A5\uC18C\uC5D0 \uC561\uC138\uC2A4\uD558\uC2ED\uC2DC\uC624."},
         {"new.password",
                 "\uC0C8 \uBE44\uBC00\uBC88\uD638"}, //-new
         {"do.not.prompt",
                 "\uD655\uC778\uD558\uC9C0 \uC54A\uC74C"}, //-noprompt
         {"password.through.protected.mechanism",
                 "\uBCF4\uD638\uB418\uB294 \uBA54\uCEE4\uB2C8\uC998\uC744 \uD1B5\uD55C \uBE44\uBC00\uBC88\uD638"}, //-protected
-        {"provider.argument",
-                "\uC81C\uACF5\uC790 \uC778\uC218"}, //-providerarg
-        {"provider.class.name",
-                "\uC81C\uACF5\uC790 \uD074\uB798\uC2A4 \uC774\uB984"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "\uC774\uB984\uBCC4 \uBCF4\uC548 \uC81C\uACF5\uC790 \uCD94\uAC00(\uC608: SunPKCS11)\n-addprovider\uC5D0 \uB300\uD55C \uC778\uC218 \uAD6C\uC131"}, //-addprovider
+        {"provider.class.option",
+                "\uC804\uCCB4 \uD074\uB798\uC2A4 \uC774\uB984\uBCC4 \uBCF4\uC548 \uC81C\uACF5\uC790 \uCD94\uAC00\n-providerclass\uC5D0 \uB300\uD55C \uC778\uC218 \uAD6C\uC131"}, //-providerclass
+
         {"provider.name",
                 "\uC81C\uACF5\uC790 \uC774\uB984"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "\uBA85\uB839 \uC635\uC158 {0}\uC5D0 \uC778\uC218\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "\uACBD\uACE0: \uB2E4\uB978 \uC800\uC7A5\uC18C \uBC0F \uD0A4 \uBE44\uBC00\uBC88\uD638\uB294 PKCS12 KeyStores\uC5D0 \uB300\uD574 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uC9C0\uC815\uD55C {0} \uAC12\uC744 \uBB34\uC2DC\uD558\uB294 \uC911\uC785\uB2C8\uB2E4."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "-keystore \uB610\uB294 -storetype \uC635\uC158\uC740 -cacerts \uC635\uC158\uACFC \uD568\uAED8 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-storetype\uC774 {0}\uC778 \uACBD\uC6B0 -keystore\uB294 NONE\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4."},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "startdate \uAC12\uC774 \uC798\uBABB\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
         {"Validity.must.be.greater.than.zero",
                 "\uC720\uD6A8 \uAE30\uAC04\uC740 0\uBCF4\uB2E4 \uCEE4\uC57C \uD569\uB2C8\uB2E4."},
-        {"provName.not.a.provider", "{0}\uC740(\uB294) \uC81C\uACF5\uC790\uAC00 \uC544\uB2D9\uB2C8\uB2E4."},
+        {"provclass.not.a.provider", "%s\uC740(\uB294) \uC81C\uACF5\uC790\uAC00 \uC544\uB2D9\uB2C8\uB2E4."},
+        {"provider.name.not.found", "\"%s\" \uC774\uB984\uC758 \uC81C\uACF5\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
+        {"provider.class.not.found", "\"%s\" \uC81C\uACF5\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
         {"Usage.error.no.command.provided", "\uC0AC\uC6A9\uBC95 \uC624\uB958: \uBA85\uB839\uC744 \uC785\uB825\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
         {"Source.keystore.file.exists.but.is.empty.", "\uC18C\uC2A4 \uD0A4 \uC800\uC7A5\uC18C \uD30C\uC77C\uC774 \uC874\uC7AC\uD558\uC9C0\uB9CC \uBE44\uC5B4 \uC788\uC74C: "},
         {"Please.specify.srckeystore", "-srckeystore\uB97C \uC9C0\uC815\uD558\uC2ED\uC2DC\uC624."},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_pt_BR.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_pt_BR.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "tamanho do bit da chave"}, //-keysize
         {"keystore.name",
                 "nome da \u00E1rea de armazenamento de chaves"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "acessar a \u00E1rea de armazenamento de chaves cacerts"}, // -cacerts
+        {"warning.cacerts.option",
+                "Advert\u00EAncia: use a op\u00E7\u00E3o -cacerts para acessar a \u00E1rea de armazenamento de chaves cacerts"},
         {"new.password",
                 "nova senha"}, //-new
         {"do.not.prompt",
                 "n\u00E3o perguntar"}, //-noprompt
         {"password.through.protected.mechanism",
                 "senha por meio de mecanismo protegido"}, //-protected
-        {"provider.argument",
-                "argumento do fornecedor"}, //-providerarg
-        {"provider.class.name",
-                "nome da classe do fornecedor"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "adicionar provedor de seguran\u00E7a por nome (por exemplo, SunPKCS11)\nconfigurar argumento para -addprovider"}, //-addprovider
+        {"provider.class.option",
+                "adicionar provedor de seguran\u00E7a por nome de classe totalmente qualificado\nconfigurar argumento para -providerclass"}, //-providerclass
+
         {"provider.name",
                 "nome do fornecedor"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "A op\u00E7\u00E3o de comando {0} precisa de um argumento."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Advert\u00EAncia: Senhas de chave e de armazenamento diferentes n\u00E3o suportadas para KeyStores PKCS12. Ignorando valor {0} especificado pelo usu\u00E1rio."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "A op\u00E7\u00E3o -keystore ou -storetype n\u00E3o pode ser usada com a op\u00E7\u00E3o -cacerts"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-keystore deve ser NONE se -storetype for {0}"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "valor da data inicial inv\u00E1lido"},
         {"Validity.must.be.greater.than.zero",
                 "A validade deve ser maior do que zero"},
-        {"provName.not.a.provider", "{0} n\u00E3o \u00E9 um fornecedor"},
+        {"provclass.not.a.provider", "%s n\u00E3o \u00E9 um fornecedor"},
+        {"provider.name.not.found", "O fornecedor chamado \"%s\" n\u00E3o foi encontrado"},
+        {"provider.class.not.found", "Fornecedor \"%s\" n\u00E3o encontrado"},
         {"Usage.error.no.command.provided", "Erro de uso: nenhum comando fornecido"},
         {"Source.keystore.file.exists.but.is.empty.", "O arquivo da \u00E1rea de armazenamento de chaves de origem existe, mas est\u00E1 vazio: "},
         {"Please.specify.srckeystore", "Especifique -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "nyckelbitstorlek"}, //-keysize
         {"keystore.name",
                 "namn p\u00E5 nyckellager"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "\u00E5tkomst till nyckellagret cacerts"}, // -cacerts
+        {"warning.cacerts.option",
+                "Varning: anv\u00E4nd alternativet -cacerts f\u00F6r att f\u00E5 \u00E5tkomst till nyckellagret cacerts"},
         {"new.password",
                 "nytt l\u00F6senord"}, //-new
         {"do.not.prompt",
                 "fr\u00E5ga inte"}, //-noprompt
         {"password.through.protected.mechanism",
                 "l\u00F6senord med skyddad mekanism"}, //-protected
-        {"provider.argument",
-                "leverant\u00F6rsargument"}, //-providerarg
-        {"provider.class.name",
-                "namn p\u00E5 leverant\u00F6rsklass"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "l\u00E4gg till s\u00E4kerhetsleverant\u00F6r per namn (t.ex. SunPKCS11)\nkonfigurera argument f\u00F6r -addprovider"}, //-addprovider
+        {"provider.class.option",
+                "l\u00E4gg till s\u00E4kerhetsleverant\u00F6r per fullt kvalificerat klassnamn\nkonfigurera argument f\u00F6r -providerclass"}, //-providerclass
+
         {"provider.name",
                 "leverant\u00F6rsnamn"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "Kommandoalternativet {0} beh\u00F6ver ett argument."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Varning!  PKCS12-nyckellager har inte st\u00F6d f\u00F6r olika l\u00F6senord f\u00F6r lagret och nyckeln. Det anv\u00E4ndarspecificerade {0}-v\u00E4rdet ignoreras."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "Alternativen -keystore och -storetype kan inte anv\u00E4ndas med alternativet -cacerts"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-keystore m\u00E5ste vara NONE om -storetype \u00E4r {0}"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "Otill\u00E5tet v\u00E4rde f\u00F6r startdatum"},
         {"Validity.must.be.greater.than.zero",
                 "Giltigheten m\u00E5ste vara st\u00F6rre \u00E4n noll"},
-        {"provName.not.a.provider", "{0} \u00E4r inte en leverant\u00F6r"},
+        {"provclass.not.a.provider", "%s \u00E4r inte en leverant\u00F6r"},
+        {"provider.name.not.found", "Leverant\u00F6ren med namnet \"%s\" hittades inte"},
+        {"provider.class.not.found", "Leverant\u00F6ren \"%s\" hittades inte"},
         {"Usage.error.no.command.provided", "Syntaxfel: inget kommando angivet"},
         {"Source.keystore.file.exists.but.is.empty.", "Nyckellagrets k\u00E4llfil finns, men \u00E4r tom: "},
         {"Please.specify.srckeystore", "Ange -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "\u5BC6\u94A5\u4F4D\u5927\u5C0F"}, //-keysize
         {"keystore.name",
                 "\u5BC6\u94A5\u5E93\u540D\u79F0"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "\u8BBF\u95EE cacerts \u5BC6\u94A5\u5E93"}, // -cacerts
+        {"warning.cacerts.option",
+                "\u8B66\u544A: \u4F7F\u7528 -cacerts \u9009\u9879\u8BBF\u95EE cacerts \u5BC6\u94A5\u5E93"},
         {"new.password",
                 "\u65B0\u53E3\u4EE4"}, //-new
         {"do.not.prompt",
                 "\u4E0D\u63D0\u793A"}, //-noprompt
         {"password.through.protected.mechanism",
                 "\u901A\u8FC7\u53D7\u4FDD\u62A4\u7684\u673A\u5236\u7684\u53E3\u4EE4"}, //-protected
-        {"provider.argument",
-                "\u63D0\u4F9B\u65B9\u53C2\u6570"}, //-providerarg
-        {"provider.class.name",
-                "\u63D0\u4F9B\u65B9\u7C7B\u540D"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "\u6309\u540D\u79F0 (\u4F8B\u5982 SunPKCS11) \u6DFB\u52A0\u5B89\u5168\u63D0\u4F9B\u65B9\n\u914D\u7F6E -addprovider \u7684\u53C2\u6570"}, //-addprovider
+        {"provider.class.option",
+                "\u6309\u5168\u9650\u5B9A\u7C7B\u540D\u6DFB\u52A0\u5B89\u5168\u63D0\u4F9B\u65B9\n\u914D\u7F6E -providerclass \u7684\u53C2\u6570"}, //-providerclass
+
         {"provider.name",
                 "\u63D0\u4F9B\u65B9\u540D\u79F0"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "\u547D\u4EE4\u9009\u9879{0}\u9700\u8981\u4E00\u4E2A\u53C2\u6570\u3002"},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "\u8B66\u544A: PKCS12 \u5BC6\u94A5\u5E93\u4E0D\u652F\u6301\u5176\u4ED6\u5B58\u50A8\u548C\u5BC6\u94A5\u53E3\u4EE4\u3002\u6B63\u5728\u5FFD\u7565\u7528\u6237\u6307\u5B9A\u7684{0}\u503C\u3002"},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "-keystore \u6216 -storetype \u9009\u9879\u4E0D\u80FD\u4E0E -cacerts \u9009\u9879\u4E00\u8D77\u4F7F\u7528"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "\u5982\u679C -storetype \u4E3A {0}, \u5219 -keystore \u5FC5\u987B\u4E3A NONE"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "\u975E\u6CD5\u5F00\u59CB\u65E5\u671F\u503C"},
         {"Validity.must.be.greater.than.zero",
                 "\u6709\u6548\u6027\u5FC5\u987B\u5927\u4E8E\u96F6"},
-        {"provName.not.a.provider", "{0}\u4E0D\u662F\u63D0\u4F9B\u65B9"},
+        {"provclass.not.a.provider", "%s\u4E0D\u662F\u63D0\u4F9B\u65B9"},
+        {"provider.name.not.found", "\u672A\u627E\u5230\u540D\u4E3A \"%s\" \u7684\u63D0\u4F9B\u65B9"},
+        {"provider.class.not.found", "\u672A\u627E\u5230\u63D0\u4F9B\u65B9 \"%s\""},
         {"Usage.error.no.command.provided", "\u7528\u6CD5\u9519\u8BEF: \u6CA1\u6709\u63D0\u4F9B\u547D\u4EE4"},
         {"Source.keystore.file.exists.but.is.empty.", "\u6E90\u5BC6\u94A5\u5E93\u6587\u4EF6\u5B58\u5728, \u4F46\u4E3A\u7A7A: "},
         {"Please.specify.srckeystore", "\u8BF7\u6307\u5B9A -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -126,16 +126,24 @@
                 "\u91D1\u9470\u4F4D\u5143\u5927\u5C0F"}, //-keysize
         {"keystore.name",
                 "\u91D1\u9470\u5132\u5B58\u5EAB\u540D\u7A31"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "\u5B58\u53D6 cacerts \u91D1\u9470\u5132\u5B58\u5EAB"}, // -cacerts
+        {"warning.cacerts.option",
+                "\u8B66\u544A: \u4F7F\u7528 -cacerts \u9078\u9805\u5B58\u53D6 cacerts \u91D1\u9470\u5132\u5B58\u5EAB"},
         {"new.password",
                 "\u65B0\u5BC6\u78BC"}, //-new
         {"do.not.prompt",
                 "\u4E0D\u8981\u63D0\u793A"}, //-noprompt
         {"password.through.protected.mechanism",
                 "\u7D93\u7531\u4FDD\u8B77\u6A5F\u5236\u7684\u5BC6\u78BC"}, //-protected
-        {"provider.argument",
-                "\u63D0\u4F9B\u8005\u5F15\u6578"}, //-providerarg
-        {"provider.class.name",
-                "\u63D0\u4F9B\u8005\u985E\u5225\u540D\u7A31"}, //-providerclass
+
+        // The following 2 values should span 2 lines, the first for the
+        // option itself, the second for its -providerArg value.
+        {"addprovider.option",
+                "\u4F7F\u7528\u540D\u7A31\u65B0\u589E\u5B89\u5168\u63D0\u4F9B\u8005 (\u4F8B\u5982 SunPKCS11)\n\u8A2D\u5B9A -addprovider \u5F15\u6578"}, //-addprovider
+        {"provider.class.option",
+                "\u4F7F\u7528\u5B8C\u6574\u985E\u5225\u540D\u7A31\u65B0\u589E\u5B89\u5168\u63D0\u4F9B\u8005\n\u8A2D\u5B9A -providerclass \u5F15\u6578"}, //-providerclass
+
         {"provider.name",
                 "\u63D0\u4F9B\u8005\u540D\u7A31"}, //-providername
         {"provider.classpath",
@@ -187,6 +195,8 @@
         {"Command.option.flag.needs.an.argument.", "\u547D\u4EE4\u9078\u9805 {0} \u9700\u8981\u5F15\u6578\u3002"},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "\u8B66\u544A: PKCS12 \u91D1\u9470\u5132\u5B58\u5EAB\u4E0D\u652F\u63F4\u4E0D\u540C\u7684\u5132\u5B58\u5EAB\u548C\u91D1\u9470\u5BC6\u78BC\u3002\u5FFD\u7565\u4F7F\u7528\u8005\u6307\u5B9A\u7684 {0} \u503C\u3002"},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "-keystore \u6216 -storetype \u9078\u9805\u4E0D\u80FD\u8207 -cacerts \u9078\u9805\u4E00\u8D77\u4F7F\u7528"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "\u5982\u679C -storetype \u70BA {0}\uFF0C\u5247 -keystore \u5FC5\u9808\u70BA NONE"},
         {"Too.many.retries.program.terminated",
@@ -208,7 +218,9 @@
         {"Illegal.startdate.value", "\u7121\u6548\u7684 startdate \u503C"},
         {"Validity.must.be.greater.than.zero",
                 "\u6709\u6548\u6027\u5FC5\u9808\u5927\u65BC\u96F6"},
-        {"provName.not.a.provider", "{0} \u4E0D\u662F\u4E00\u500B\u63D0\u4F9B\u8005"},
+        {"provclass.not.a.provider", "%s \u4E0D\u662F\u4E00\u500B\u63D0\u4F9B\u8005"},
+        {"provider.name.not.found", "\u627E\u4E0D\u5230\u540D\u7A31\u70BA \"%s\" \u7684\u63D0\u4F9B\u8005"},
+        {"provider.class.not.found", "\u627E\u4E0D\u5230\u63D0\u4F9B\u8005 \"%s\""},
         {"Usage.error.no.command.provided", "\u7528\u6CD5\u932F\u8AA4: \u672A\u63D0\u4F9B\u547D\u4EE4"},
         {"Source.keystore.file.exists.but.is.empty.", "\u4F86\u6E90\u91D1\u9470\u5132\u5B58\u5EAB\u6A94\u6848\u5B58\u5728\uFF0C\u4F46\u70BA\u7A7A: "},
         {"Please.specify.srckeystore", "\u8ACB\u6307\u5B9A -srckeystore"},
--- a/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
 import javax.security.auth.x500.X500Principal;
 
 import sun.security.x509.X509CertImpl;
+import sun.security.x509.KeyIdentifier;
 import sun.security.x509.NetscapeCertTypeExtension;
 import sun.security.util.DerValue;
 import sun.security.util.DerInputStream;
@@ -386,8 +387,21 @@
         X500Principal issuer = cert.getIssuerX500Principal();
         List<X509Certificate> list = trustedX500Principals.get(issuer);
         if (list != null) {
-            X509Certificate trustedCert = list.iterator().next();
-            c.add(trustedCert);
+            X509Certificate matchedCert = list.get(0);
+            X509CertImpl certImpl = X509CertImpl.toImpl(cert);
+            KeyIdentifier akid = certImpl.getAuthKeyId();
+            if (akid != null) {
+                for (X509Certificate sup : list) {
+                    // Look for a best match issuer.
+                    X509CertImpl supCert = X509CertImpl.toImpl(sup);
+                    if (akid.equals(supCert.getSubjectKeyId())) {
+                        matchedCert = sup;
+                        break;
+                    }
+                }
+            }
+
+            c.add(matchedCert);
             return c.toArray(CHAIN0);
         }
 
--- a/jdk/src/java.base/share/lib/security/default.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/lib/security/default.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -20,6 +20,9 @@
     permission java.security.AllPermission;
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+};
+
 grant codeBase "jrt:/java.scripting" {
     permission java.security.AllPermission;
 };
--- a/jdk/src/java.base/share/native/libjava/jni_util.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/share/native/libjava/jni_util.c	Tue Dec 13 02:04:23 2016 +0100
@@ -201,12 +201,14 @@
                 jio_snprintf(str1, messageextlen, " (%s)", message);
                 s2 = (*env)->NewStringUTF(env, str1);
                 free(str1);
+                JNU_CHECK_EXCEPTION(env);
                 if (s2 != NULL) {
                     jstring s3 = JNU_CallMethodByName(
                                      env, NULL, s, "concat",
                                      "(Ljava/lang/String;)Ljava/lang/String;",
                                      s2).l;
                     (*env)->DeleteLocalRef(env, s2);
+                    JNU_CHECK_EXCEPTION(env);
                     if (s3 != NULL) {
                         (*env)->DeleteLocalRef(env, s);
                         s = s3;
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,6 +76,10 @@
         return truncate0(fd, size);
     }
 
+    int allocate(FileDescriptor fd, long size) throws IOException {
+        return allocate0(fd, size);
+    }
+
     long size(FileDescriptor fd) throws IOException {
         return size0(fd);
     }
@@ -138,6 +142,9 @@
     static native int truncate0(FileDescriptor fd, long size)
         throws IOException;
 
+    static native int allocate0(FileDescriptor fd, long size)
+        throws IOException;
+
     static native long size0(FileDescriptor fd) throws IOException;
 
     static native int lock0(FileDescriptor fd, boolean blocking, long pos,
--- a/jdk/src/java.base/unix/native/libjava/io_util_md.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/unix/native/libjava/io_util_md.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -215,6 +215,20 @@
 handleSetLength(FD fd, jlong length)
 {
     int result;
+#if defined(__linux__)
+    /*
+     * On Linux, if the file size is being increased, then ftruncate64()
+     * will modify the metadata value of the size without actually allocating
+     * any blocks which can cause a SIGBUS error if the file is subsequently
+     * memory-mapped.
+     */
+    struct stat64 sb;
+
+    if (fstat64(fd, &sb) == 0 && length > sb.st_blocks*512) {
+        RESTARTABLE(fallocate64(fd, 0, 0, length), result);
+        return result;
+    }
+#endif
     RESTARTABLE(ftruncate64(fd, length), result);
     return result;
 }
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c	Tue Dec 13 02:04:23 2016 +0100
@@ -45,6 +45,10 @@
 #include <sys/sockio.h>
 #endif
 
+#if defined(MACOSX)
+#include <sys/sysctl.h>
+#endif
+
 #include "net_util.h"
 
 #include "java_net_SocketOptions.h"
--- a/jdk/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, 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
@@ -186,6 +186,27 @@
                   "Truncation failed");
 }
 
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_allocate0(JNIEnv *env, jobject this,
+                                             jobject fdo, jlong size)
+{
+#if defined(__linux__)
+    /*
+     * On Linux, if the file size is being increased, then ftruncate64()
+     * will modify the metadata value of the size without actually allocating
+     * any blocks which can cause a SIGBUS error if the file is subsequently
+     * memory-mapped.
+     */
+    return handle(env,
+                  fallocate64(fdval(env, fdo), 0, 0, size),
+                  "Allocation failed");
+#else
+    return handle(env,
+                  ftruncate64(fdval(env, fdo), size),
+                  "Truncation failed");
+#endif
+}
+
 JNIEXPORT jlong JNICALL
 Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
 {
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,6 +84,11 @@
         return truncate0(fd, size);
     }
 
+    int allocate(FileDescriptor fd, long size) throws IOException {
+        // truncate0() works for extending and truncating file size
+        return truncate0(fd, size);
+    }
+
     long size(FileDescriptor fd) throws IOException {
         return size0(fd);
     }
--- a/jdk/src/java.desktop/share/native/libawt/awt/image/DataBufferNative.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/share/native/libawt/awt/image/DataBufferNative.c	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -72,6 +72,7 @@
     unsigned char *pixelPtr;
     SurfaceDataRasInfo lockInfo;
     SurfaceDataOps *ops;
+    lockInfo.rasBase = NULL;
 
     ops = SurfaceData_GetOps(env, sd);
     JNU_CHECK_EXCEPTION_RETURN(env, -1);
@@ -113,7 +114,7 @@
     SurfaceDataRasInfo lockInfo;
     SurfaceDataOps *ops;
     unsigned char *pixelPtr;
-
+    lockInfo.rasBase = NULL;
 
     ops = SurfaceData_GetOps(env, sd);
     JNU_CHECK_EXCEPTION(env);
--- a/jdk/src/java.desktop/unix/native/common/awt/fontpath.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/unix/native/common/awt/fontpath.c	Tue Dec 13 02:04:23 2016 +0100
@@ -243,8 +243,8 @@
 
         appendDirList[index] = 0;
         if ( doNotAppend == 0 ) {
-            strcpy ( fontDirPath, fDirP->name[index] );
-            strcat ( fontDirPath, "/fonts.dir" );
+            snprintf(fontDirPath, sizeof(fontDirPath), "%s/fonts.dir", fDirP->name[index]);
+            fontDirPath[sizeof(fontDirPath) - 1] = '\0';
             dirFile = open ( fontDirPath, O_RDONLY, 0 );
             if ( dirFile == -1 ) {
                 doNotAppend = 1;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -1235,12 +1235,14 @@
     if (status_draw->type == XIMTextType){
         XIMText *text = (status_draw->data).text;
         if (text != NULL){
-          if (text->string.multi_byte != NULL){
-              strcpy(statusWindow->status, text->string.multi_byte);
+          if (text->string.multi_byte != NULL) {
+              strncpy(statusWindow->status, text->string.multi_byte, MAX_STATUS_LEN);
+              statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
           }
-          else{
+          else {
               char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
-              strcpy(statusWindow->status, mbstr);
+              strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN);
+              statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
           }
           statusWindow->on = True;
           onoffStatusWindow(pX11IMData, statusWindow->parent, True);
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Tue Dec 13 02:04:23 2016 +0100
@@ -2014,9 +2014,7 @@
 static guint8 recode_color(gdouble channel)
 {
     guint16 result = (guint16)(channel * 65535);
-    if (result < 0) {
-        result = 0;
-    } else if (result > 65535) {
+    if (result > 65535) {
         result = 65535;
     }
     return (guint8)( result >> 8);
@@ -2218,6 +2216,7 @@
 static GdkRGBA gtk3_get_color_for_flags(GtkStyleContext* context,
                                   GtkStateFlags flags, ColorType color_type) {
     GdkRGBA c, color;
+    color.alpha = 1;
 
     switch (color_type)
     {
@@ -2266,7 +2265,6 @@
 {
 
     gint result = 0;
-    GdkRGBA color;
 
     GtkStateFlags flags = gtk3_get_state_flags(state_type);
 
@@ -2285,7 +2283,7 @@
                   | GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_FOCUSED;
     }
 
-    color = gtk3_get_color_for_flags(context, flags, color_type);
+    GdkRGBA color = gtk3_get_color_for_flags(context, flags, color_type);
 
     if (recode_color(color.alpha) == 0) {
         color = gtk3_get_color_for_flags(
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Tue Dec 13 02:04:23 2016 +0100
@@ -567,7 +567,7 @@
  */
 static uint32_t get_poll_timeout(jlong nextTaskTime)
 {
-    uint32_t ret_timeout;
+    uint32_t ret_timeout = 0;
     uint32_t timeout;
     uint32_t taskTimeout;
     uint32_t flushTimeout;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XWindow.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XWindow.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -863,10 +863,10 @@
 }
 static void
 dumpKeysymArray(XEvent *event) {
-    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
-    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
-    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
-    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
+    printf("    0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
+    printf("    0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
+    printf("    0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
+    printf("    0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
 }
 /*
  * In a next redesign, get rid of this code altogether.
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -809,7 +809,7 @@
 #ifndef __linux__
     return JNI_FALSE;
 #endif
-    *scaleFactor = getNativeScaleFactor(NULL);
+    *scaleFactor = (float)getNativeScaleFactor(NULL);
     return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
 }
 
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.util.function.Consumer;
-
-/**
- * Implemented by classes that offer an asynchronous interface.
- *
- * PlainHttpConnection, AsyncSSLConnection AsyncSSLDelegate.
- *
- * setAsyncCallbacks() is called to set the callback for reading
- * and error notification. Reads all happen on the selector thread, which
- * must not block.
- *
- * Writing uses the same write() methods as used in blocking mode.
- * Queues are employed on the writing side to buffer data while it is waiting
- * to be sent. This strategy relies on HTTP/2 protocol flow control to stop
- * outgoing queue from continually growing. Writes can be initiated by the
- * calling thread, but if socket becomes full then the queue is emptied by
- * the selector thread
- *
- */
-interface AsyncConnection {
-
-    /**
-     * Enables asynchronous sending and receiving mode. The given async
-     * receiver will receive all incoming data. asyncInput() will be called
-     * to trigger reads. asyncOutput() will be called to drive writes.
-     *
-     * The errorReceiver callback must be called when any fatal exception
-     * occurs. Connection is assumed to be closed afterwards.
-     *
-     * @param asyncReceiver
-     * @param errorReceiver
-     */
-    void setAsyncCallbacks(
-            Consumer<ByteBuffer> asyncReceiver,
-            Consumer<Throwable> errorReceiver);
-
-    /**
-     * Does whatever is required to start reading. Usually registers
-     * an event with the selector thread.
-     */
-    void startReading();
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncEvent.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-
-/**
- * Event handling interface from HttpClientImpl's selector.
- *
- * If BLOCKING is set, then the channel will be put in blocking
- * mode prior to handle() being called. If false, then it remains non-blocking.
- *
- * If REPEATING is set then the event is not cancelled after being posted.
- */
-abstract class AsyncEvent {
-
-    public static final int BLOCKING = 0x1; // non blocking if not set
-    public static final int REPEATING = 0x2; // one off event if not set
-
-    protected final int flags;
-
-    AsyncEvent(int flags) {
-        this.flags = flags;
-    }
-
-    /** Returns the channel */
-    public abstract SelectableChannel channel();
-
-    /** Returns the selector interest op flags OR'd */
-    public abstract int interestOps();
-
-    /** Called when event occurs */
-    public abstract void handle();
-
-    /** Called when selector is shutting down. Abort all exchanges. */
-    public abstract void abort();
-
-    public boolean blocking() {
-        return (flags & BLOCKING) != 0;
-    }
-
-    public boolean repeating() {
-        return (flags & REPEATING) != 0;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.Consumer;
-
-/**
- * Asynchronous version of SSLConnection.
- */
-class AsyncSSLConnection extends HttpConnection implements AsyncConnection {
-    final AsyncSSLDelegate sslDelegate;
-    final PlainHttpConnection delegate;
-
-    AsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) {
-        super(addr, client);
-        delegate = new PlainHttpConnection(addr, client);
-        sslDelegate = new AsyncSSLDelegate(delegate, client, ap);
-    }
-
-    @Override
-    public void connect() throws IOException, InterruptedException {
-        delegate.connect();
-    }
-
-    @Override
-    public CompletableFuture<Void> connectAsync() {
-        return delegate.connectAsync();
-    }
-
-    @Override
-    boolean connected() {
-        return delegate.connected();
-    }
-
-    @Override
-    boolean isSecure() {
-        return true;
-    }
-
-    @Override
-    boolean isProxied() {
-        return false;
-    }
-
-    @Override
-    SocketChannel channel() {
-        return delegate.channel();
-    }
-
-    @Override
-    ConnectionPool.CacheKey cacheKey() {
-        return ConnectionPool.cacheKey(address, null);
-    }
-
-    @Override
-    synchronized long write(ByteBuffer[] buffers, int start, int number) throws IOException {
-        ByteBuffer[] bufs = Utils.reduce(buffers, start, number);
-        long n = Utils.remaining(bufs);
-        sslDelegate.write(bufs);
-        return n;
-    }
-
-    @Override
-    long write(ByteBuffer buffer) throws IOException {
-        long n = buffer.remaining();
-        sslDelegate.write(buffer);
-        return n;
-    }
-
-    @Override
-    public void close() {
-        Utils.close(sslDelegate, delegate.channel());
-    }
-
-    @Override
-    public void setAsyncCallbacks(Consumer<ByteBuffer> asyncReceiver, Consumer<Throwable> errorReceiver) {
-        sslDelegate.setAsyncCallbacks(asyncReceiver, errorReceiver);
-        delegate.setAsyncCallbacks(sslDelegate::lowerRead, errorReceiver);
-    }
-
-    // Blocking read functions not used here
-
-    @Override
-    protected ByteBuffer readImpl(int length) throws IOException {
-        throw new UnsupportedOperationException("Not supported.");
-    }
-
-    @Override
-    protected int readImpl(ByteBuffer buffer) throws IOException {
-        throw new UnsupportedOperationException("Not supported.");
-    }
-
-    @Override
-    CompletableFuture<Void> whenReceivingResponse() {
-        throw new UnsupportedOperationException("Not supported.");
-    }
-
-    @Override
-    public void startReading() {
-        delegate.startReading();
-        sslDelegate.startReading();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,609 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.Closeable;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.concurrent.ExecutorService;
-import java.util.function.Consumer;
-import static javax.net.ssl.SSLEngineResult.Status.*;
-import javax.net.ssl.*;
-import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
-
-/**
- * Asynchronous wrapper around SSLEngine. send and receive is fully non
- * blocking. When handshaking is required, a thread is created to perform
- * the handshake and application level sends do not take place during this time.
- *
- * Is implemented using queues and functions operating on the receiving end
- * of each queue.
- *
- * Application writes to:
- *        ||
- *        \/
- *     appOutputQ
- *        ||
- *        \/
- * appOutputQ read by "upperWrite" method which does SSLEngine.wrap
- * and writes to
- *        ||
- *        \/
- *     channelOutputQ
- *        ||
- *        \/
- * channelOutputQ is read by "lowerWrite" method which is invoked from
- * OP_WRITE events on the socket (from selector thread)
- *
- * Reading side is as follows
- * --------------------------
- *
- * "upperRead" method reads off channelInputQ and calls SSLEngine.unwrap and
- * when decrypted data is returned, it is passed to the user's Consumer<ByteBuffer>
- *        /\
- *        ||
- *     channelInputQ
- *        /\
- *        ||
- * "lowerRead" method puts buffers into channelInputQ. It is invoked from
- * OP_READ events from the selector.
- *
- * Whenever handshaking is required, the doHandshaking() method is called
- * which creates a thread to complete the handshake. It takes over the
- * channelInputQ from upperRead, and puts outgoing packets on channelOutputQ.
- * Selector events are delivered to lowerRead and lowerWrite as normal.
- *
- * Errors
- *
- * Any exception thrown by the engine or channel, causes all Queues to be closed
- * the channel to be closed, and the error is reported to the user's
- * Consumer<Throwable>
- */
-class AsyncSSLDelegate implements Closeable, AsyncConnection {
-
-    // outgoing buffers put in this queue first and may remain here
-    // while SSL handshaking happening.
-    final Queue<ByteBuffer> appOutputQ;
-
-    // queue of wrapped ByteBuffers waiting to be sent on socket channel
-    //final Queue<ByteBuffer> channelOutputQ;
-
-    // Bytes read into this queue before being unwrapped. Backup on this
-    // Q should only happen when the engine is stalled due to delegated tasks
-    final Queue<ByteBuffer> channelInputQ;
-
-    // input occurs through the read() method which is expected to be called
-    // when the selector signals some data is waiting to be read. All incoming
-    // handshake data is handled in this method, which means some calls to
-    // read() may return zero bytes of user data. This is not a sign of spinning,
-    // just that the handshake mechanics are being executed.
-
-    final SSLEngine engine;
-    final SSLParameters sslParameters;
-    //final SocketChannel chan;
-    final HttpConnection lowerOutput;
-    final HttpClientImpl client;
-    final ExecutorService executor;
-    final BufferHandler bufPool;
-    Consumer<ByteBuffer> receiver;
-    Consumer<Throwable> errorHandler;
-    // Locks.
-    final Object reader = new Object();
-    final Object writer = new Object();
-    // synchronizing handshake state
-    final Object handshaker = new Object();
-    // flag set when reader or writer is blocked waiting for handshake to finish
-    boolean writerBlocked;
-    boolean readerBlocked;
-
-    // some thread is currently doing the handshake
-    boolean handshaking;
-
-    // alpn[] may be null. upcall is callback which receives incoming decoded bytes off socket
-
-    AsyncSSLDelegate(HttpConnection lowerOutput, HttpClientImpl client, String[] alpn)
-    {
-        SSLContext context = client.sslContext();
-        executor = client.executorService();
-        bufPool = client;
-        appOutputQ = new Queue<>();
-        appOutputQ.registerPutCallback(this::upperWrite);
-        //channelOutputQ = new Queue<>();
-        //channelOutputQ.registerPutCallback(this::lowerWrite);
-        engine = context.createSSLEngine();
-        engine.setUseClientMode(true);
-        SSLParameters sslp = client.sslParameters().orElse(null);
-        if (sslp == null) {
-            sslp = context.getSupportedSSLParameters();
-            //sslp = context.getDefaultSSLParameters();
-            //printParams(sslp);
-        }
-        sslParameters = Utils.copySSLParameters(sslp);
-        if (alpn != null) {
-            sslParameters.setApplicationProtocols(alpn);
-        }
-        logParams(sslParameters);
-        engine.setSSLParameters(sslParameters);
-        this.lowerOutput = lowerOutput;
-        this.client = client;
-        this.channelInputQ = new Queue<>();
-        this.channelInputQ.registerPutCallback(this::upperRead);
-    }
-
-    /**
-     * Put buffers to appOutputQ, and call upperWrite() if q was empty.
-     *
-     * @param src
-     */
-    public void write(ByteBuffer[] src) throws IOException {
-        appOutputQ.putAll(src);
-    }
-
-    public void write(ByteBuffer buf) throws IOException {
-        ByteBuffer[] a = new ByteBuffer[1];
-        a[0] = buf;
-        write(a);
-    }
-
-    @Override
-    public void close() {
-        Utils.close(appOutputQ, channelInputQ, lowerOutput);
-    }
-
-    /**
-     * Attempts to wrap buffers from appOutputQ and place them on the
-     * channelOutputQ for writing. If handshaking is happening, then the
-     * process stalls and last buffers taken off the appOutputQ are put back
-     * into it until handshaking completes.
-     *
-     * This same method is called to try and resume output after a blocking
-     * handshaking operation has completed.
-     */
-    private void upperWrite() {
-        try {
-            EngineResult r = null;
-            ByteBuffer[] buffers = appOutputQ.pollAll(Utils.EMPTY_BB_ARRAY);
-            int bytes = Utils.remaining(buffers);
-            while (bytes > 0) {
-                synchronized (writer) {
-                    r = wrapBuffers(buffers);
-                    int bytesProduced = r.bytesProduced();
-                    int bytesConsumed = r.bytesConsumed();
-                    bytes -= bytesConsumed;
-                    if (bytesProduced > 0) {
-                        // pass destination buffer to channelOutputQ.
-                        lowerOutput.write(r.destBuffer);
-                    }
-                    synchronized (handshaker) {
-                        if (r.handshaking()) {
-                            // handshaking is happening or is needed
-                            // so we put the buffers back on Q to process again
-                            // later. It's possible that some may have already
-                            // been processed, which is ok.
-                            appOutputQ.pushbackAll(buffers);
-                            writerBlocked = true;
-                            if (!handshaking()) {
-                                // execute the handshake in another thread.
-                                // This method will be called again to resume sending
-                                // later
-                                doHandshake(r);
-                            }
-                            return;
-                        }
-                    }
-                }
-            }
-            returnBuffers(buffers);
-        } catch (Throwable t) {
-            close();
-            errorHandler.accept(t);
-        }
-    }
-
-    private void doHandshake(EngineResult r) {
-        handshaking = true;
-        channelInputQ.registerPutCallback(null);
-        executor.execute(() -> {
-            try {
-                doHandshakeImpl(r);
-                channelInputQ.registerPutCallback(this::upperRead);
-            } catch (Throwable t) {
-                close();
-                errorHandler.accept(t);
-            }
-        });
-    }
-
-    private void returnBuffers(ByteBuffer[] bufs) {
-        for (ByteBuffer buf : bufs)
-            client.returnBuffer(buf);
-    }
-
-    /**
-     * Return true if some thread is currently doing the handshake
-     *
-     * @return
-     */
-    boolean handshaking() {
-        synchronized(handshaker) {
-            return handshaking;
-        }
-    }
-
-    /**
-     * Executes entire handshake in calling thread.
-     * Returns after handshake is completed or error occurs
-     * @param r
-     * @throws IOException
-     */
-    private void doHandshakeImpl(EngineResult r) throws IOException {
-        while (true) {
-            SSLEngineResult.HandshakeStatus status = r.handshakeStatus();
-            if (status == NEED_TASK) {
-                LinkedList<Runnable> tasks = obtainTasks();
-                for (Runnable task : tasks)
-                    task.run();
-                r = handshakeWrapAndSend();
-            } else if (status == NEED_WRAP) {
-                r = handshakeWrapAndSend();
-            } else if (status == NEED_UNWRAP) {
-                r = handshakeReceiveAndUnWrap();
-            }
-            if (!r.handshaking())
-                break;
-        }
-        boolean dowrite = false;
-        boolean doread = false;
-        // Handshake is finished. Now resume reading and/or writing
-        synchronized(handshaker) {
-            handshaking = false;
-            if (writerBlocked) {
-                writerBlocked = false;
-                dowrite = true;
-            }
-            if (readerBlocked) {
-                readerBlocked = false;
-                doread = true;
-            }
-        }
-        if (dowrite)
-            upperWrite();
-        if (doread)
-            upperRead();
-    }
-
-    // acknowledge a received CLOSE request from peer
-    void doClosure() throws IOException {
-        //while (!wrapAndSend(emptyArray))
-            //;
-    }
-
-    LinkedList<Runnable> obtainTasks() {
-        LinkedList<Runnable> l = new LinkedList<>();
-        Runnable r;
-        while ((r = engine.getDelegatedTask()) != null)
-            l.add(r);
-        return l;
-    }
-
-    @Override
-    public synchronized void setAsyncCallbacks(Consumer<ByteBuffer> asyncReceiver, Consumer<Throwable> errorReceiver) {
-        this.receiver = asyncReceiver;
-        this.errorHandler = errorReceiver;
-    }
-
-    @Override
-    public void startReading() {
-        // maybe this class does not need to implement AsyncConnection
-    }
-
-    static class EngineResult {
-        ByteBuffer destBuffer;
-        ByteBuffer srcBuffer;
-        SSLEngineResult result;
-        Throwable t;
-
-        boolean handshaking() {
-            SSLEngineResult.HandshakeStatus s = result.getHandshakeStatus();
-            return s != FINISHED && s != NOT_HANDSHAKING;
-        }
-
-        int bytesConsumed() {
-            return result.bytesConsumed();
-        }
-
-        int bytesProduced() {
-            return result.bytesProduced();
-        }
-
-        Throwable exception() {
-            return t;
-        }
-
-        SSLEngineResult.HandshakeStatus handshakeStatus() {
-            return result.getHandshakeStatus();
-        }
-
-        SSLEngineResult.Status status() {
-            return result.getStatus();
-        }
-    }
-
-    EngineResult handshakeWrapAndSend() throws IOException {
-        EngineResult r = wrapBuffer(Utils.EMPTY_BYTEBUFFER);
-        if (r.bytesProduced() > 0) {
-            lowerOutput.write(r.destBuffer);
-        }
-        return r;
-    }
-
-    // called during handshaking. It blocks until a complete packet
-    // is available, unwraps it and returns.
-    EngineResult handshakeReceiveAndUnWrap() throws IOException {
-        ByteBuffer buf = channelInputQ.take();
-        while (true) {
-            // block waiting for input
-            EngineResult r = unwrapBuffer(buf);
-            SSLEngineResult.Status status = r.status();
-            if (status == BUFFER_UNDERFLOW) {
-                // wait for another buffer to arrive
-                ByteBuffer buf1 = channelInputQ.take();
-                buf = combine (buf, buf1);
-                continue;
-            }
-            // OK
-            // theoretically possible we could receive some user data
-            if (r.bytesProduced() > 0) {
-                receiver.accept(r.destBuffer);
-            }
-            if (!buf.hasRemaining())
-                return r;
-        }
-    }
-
-    EngineResult wrapBuffer(ByteBuffer src) throws SSLException {
-        ByteBuffer[] bufs = new ByteBuffer[1];
-        bufs[0] = src;
-        return wrapBuffers(bufs);
-    }
-
-    EngineResult wrapBuffers(ByteBuffer[] src) throws SSLException {
-        EngineResult r = new EngineResult();
-        ByteBuffer dst = bufPool.getBuffer();
-        while (true) {
-            r.result = engine.wrap(src, dst);
-            switch (r.result.getStatus()) {
-                case BUFFER_OVERFLOW:
-                    dst = getPacketBuffer();
-                    break;
-                case CLOSED:
-                case OK:
-                    dst.flip();
-                    r.destBuffer = dst;
-                    return r;
-                case BUFFER_UNDERFLOW:
-                    // underflow handled externally
-                    bufPool.returnBuffer(dst);
-                    return r;
-                default:
-                    assert false;
-            }
-        }
-    }
-
-    EngineResult unwrapBuffer(ByteBuffer srcbuf) throws IOException {
-        EngineResult r = new EngineResult();
-        r.srcBuffer = srcbuf;
-
-        ByteBuffer dst = bufPool.getBuffer();
-        while (true) {
-            r.result = engine.unwrap(srcbuf, dst);
-            switch (r.result.getStatus()) {
-                case BUFFER_OVERFLOW:
-                    // dest buffer not big enough. Reallocate
-                    int oldcap = dst.capacity();
-                    dst = getApplicationBuffer();
-                    assert dst.capacity() > oldcap;
-                    break;
-                case CLOSED:
-                    doClosure();
-                    throw new IOException("Engine closed");
-                case BUFFER_UNDERFLOW:
-                    bufPool.returnBuffer(dst);
-                    return r;
-                case OK:
-                    dst.flip();
-                    r.destBuffer = dst;
-                    return r;
-            }
-        }
-    }
-
-    /**
-     * Asynchronous read input. Call this when selector fires.
-     * Unwrap done in upperRead because it also happens in
-     * doHandshake() when handshake taking place
-     */
-    public void lowerRead(ByteBuffer buffer) {
-        try {
-            channelInputQ.put(buffer);
-        } catch (Throwable t) {
-            close();
-            errorHandler.accept(t);
-        }
-    }
-
-    public void upperRead() {
-        EngineResult r;
-        ByteBuffer srcbuf;
-        synchronized (reader) {
-            try {
-                srcbuf = channelInputQ.poll();
-                if (srcbuf == null) {
-                    return;
-                }
-                while (true) {
-                    r = unwrapBuffer(srcbuf);
-                    switch (r.result.getStatus()) {
-                        case BUFFER_UNDERFLOW:
-                            // Buffer too small. Need to combine with next buf
-                            ByteBuffer nextBuf = channelInputQ.poll();
-                            if (nextBuf == null) {
-                                // no data available. push buffer back until more data available
-                                channelInputQ.pushback(srcbuf);
-                                return;
-                            } else {
-                                srcbuf = combine(srcbuf, nextBuf);
-                            }
-                            break;
-                        case OK:
-                            // check for any handshaking work
-                            synchronized (handshaker) {
-                                if (r.handshaking()) {
-                                    // handshaking is happening or is needed
-                                    // so we put the buffer back on Q to process again
-                                    // later.
-                                    channelInputQ.pushback(srcbuf);
-                                    readerBlocked = true;
-                                    if (!handshaking()) {
-                                        // execute the handshake in another thread.
-                                        // This method will be called again to resume sending
-                                        // later
-                                        doHandshake(r);
-                                    }
-                                    return;
-                                }
-                            }
-                            ByteBuffer dst = r.destBuffer;
-                            if (dst.hasRemaining()) {
-                                receiver.accept(dst);
-                            }
-                    }
-                    if (srcbuf.hasRemaining()) {
-                        continue;
-                    }
-                    srcbuf = channelInputQ.poll();
-                    if (srcbuf == null) {
-                        return;
-                    }
-                }
-            } catch (Throwable t) {
-                close();
-                errorHandler.accept(t);
-            }
-        }
-    }
-
-    /**
-     * Get a new buffer that is the right size for application buffers.
-     *
-     * @return
-     */
-    ByteBuffer getApplicationBuffer() {
-        SSLSession session = engine.getSession();
-        int appBufsize = session.getApplicationBufferSize();
-        bufPool.setMinBufferSize(appBufsize);
-        return bufPool.getBuffer(appBufsize);
-    }
-
-    ByteBuffer getPacketBuffer() {
-        SSLSession session = engine.getSession();
-        int packetBufSize = session.getPacketBufferSize();
-        bufPool.setMinBufferSize(packetBufSize);
-        return bufPool.getBuffer(packetBufSize);
-    }
-
-    ByteBuffer combine(ByteBuffer buf1, ByteBuffer buf2) {
-        int avail1 = buf1.capacity() - buf1.remaining();
-        if (buf2.remaining() < avail1) {
-            buf1.compact();
-            buf1.put(buf2);
-            buf1.flip();
-            return buf1;
-        }
-        int newsize = buf1.remaining() + buf2.remaining();
-        ByteBuffer newbuf = bufPool.getBuffer(newsize);
-        newbuf.put(buf1);
-        newbuf.put(buf2);
-        newbuf.flip();
-        return newbuf;
-    }
-
-    SSLParameters getSSLParameters() {
-        return sslParameters;
-    }
-
-    static void logParams(SSLParameters p) {
-        if (!Log.ssl()) {
-            return;
-        }
-
-        Log.logSSL("SSLParameters:");
-        if (p == null) {
-            Log.logSSL("Null params");
-            return;
-        }
-
-        if (p.getCipherSuites() != null) {
-            for (String cipher : p.getCipherSuites()) {
-                Log.logSSL("cipher: {0}\n", cipher);
-            }
-        }
-
-        // SSLParameters.getApplicationProtocols() can't return null
-        for (String approto : p.getApplicationProtocols()) {
-            Log.logSSL("application protocol: {0}\n", approto);
-        }
-
-        if (p.getProtocols() != null) {
-            for (String protocol : p.getProtocols()) {
-                Log.logSSL("protocol: {0}\n", protocol);
-            }
-        }
-
-        if (p.getServerNames() != null) {
-            for (SNIServerName sname : p.getServerNames()) {
-                Log.logSSL("server name: {0}\n", sname.toString());
-            }
-        }
-    }
-
-    String getSessionInfo() {
-        StringBuilder sb = new StringBuilder();
-        String application = engine.getApplicationProtocol();
-        SSLSession sess = engine.getSession();
-        String cipher = sess.getCipherSuite();
-        String protocol = sess.getProtocol();
-        sb.append("Handshake complete alpn: ")
-                .append(application)
-                .append(", Cipher: ")
-                .append(cipher)
-                .append(", Protocol: ")
-                .append(protocol);
-        return sb.toString();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AuthenticationFilter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 static java.net.Authenticator.RequestorType.PROXY;
-import static java.net.Authenticator.RequestorType.SERVER;
-import java.net.PasswordAuthentication;
-import java.net.URI;
-import java.net.InetSocketAddress;
-import java.net.URISyntaxException;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.LinkedList;
-import static java.nio.charset.StandardCharsets.ISO_8859_1;
-
-/**
- * Implementation of Http Basic authentication.
- */
-class AuthenticationFilter implements HeaderFilter {
-
-    static private final Base64.Encoder encoder = Base64.getEncoder();
-
-    static final int DEFAULT_RETRY_LIMIT = 3;
-
-    static final int retry_limit = Utils.getIntegerNetProperty(
-            "java.net.httpclient.auth.retrylimit", DEFAULT_RETRY_LIMIT);
-
-    static final int UNAUTHORIZED = 401;
-    static final int PROXY_UNAUTHORIZED = 407;
-
-    private PasswordAuthentication getCredentials(String header,
-                                                  boolean proxy,
-                                                  HttpRequestImpl req)
-        throws IOException
-    {
-        HttpClientImpl client = req.client();
-        java.net.Authenticator auth =
-                client.authenticator()
-                      .orElseThrow(() -> new IOException("No authenticator set"));
-        URI uri = req.uri();
-        HeaderParser parser = new HeaderParser(header);
-        String authscheme = parser.findKey(0);
-
-        String realm = parser.findValue("realm");
-        java.net.Authenticator.RequestorType rtype = proxy ? PROXY : SERVER;
-
-        // needs to be instance method in Authenticator
-        return auth.requestPasswordAuthenticationInstance(uri.getHost(),
-                                                          null,
-                                                          uri.getPort(),
-                                                          uri.getScheme(),
-                                                          realm,
-                                                          authscheme,
-                                                          uri.toURL(),
-                                                          rtype
-        );
-    }
-
-    private URI getProxyURI(HttpRequestImpl r) {
-        InetSocketAddress proxy = r.proxy();
-        if (proxy == null) {
-            return null;
-        }
-
-        // our own private scheme for proxy URLs
-        // eg. proxy.http://host:port/
-        String scheme = "proxy." + r.uri().getScheme();
-        try {
-            return new URI(scheme,
-                           null,
-                           proxy.getHostString(),
-                           proxy.getPort(),
-                           null,
-                           null,
-                           null);
-        } catch (URISyntaxException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    @Override
-    public void request(HttpRequestImpl r) throws IOException {
-        // use preemptive authentication if an entry exists.
-        Cache cache = getCache(r);
-
-        // Proxy
-        if (r.exchange.proxyauth == null) {
-            URI proxyURI = getProxyURI(r);
-            if (proxyURI != null) {
-                CacheEntry ca = cache.get(proxyURI, true);
-                if (ca != null) {
-                    r.exchange.proxyauth = new AuthInfo(true, ca.scheme, null, ca);
-                    addBasicCredentials(r, true, ca.value);
-                }
-            }
-        }
-
-        // Server
-        if (r.exchange.serverauth == null) {
-            CacheEntry ca = cache.get(r.uri(), false);
-            if (ca != null) {
-                r.exchange.serverauth = new AuthInfo(true, ca.scheme, null, ca);
-                addBasicCredentials(r, false, ca.value);
-            }
-        }
-    }
-
-    // TODO: refactor into per auth scheme class
-    static private void addBasicCredentials(HttpRequestImpl r,
-                                            boolean proxy,
-                                            PasswordAuthentication pw) {
-        String hdrname = proxy ? "Proxy-Authorization" : "Authorization";
-        StringBuilder sb = new StringBuilder(128);
-        sb.append(pw.getUserName()).append(':').append(pw.getPassword());
-        String s = encoder.encodeToString(sb.toString().getBytes(ISO_8859_1));
-        String value = "Basic " + s;
-        r.setSystemHeader(hdrname, value);
-    }
-
-    // Information attached to a HttpRequestImpl relating to authentication
-    static class AuthInfo {
-        final boolean fromcache;
-        final String scheme;
-        int retries;
-        PasswordAuthentication credentials; // used in request
-        CacheEntry cacheEntry; // if used
-
-        AuthInfo(boolean fromcache,
-                 String scheme,
-                 PasswordAuthentication credentials) {
-            this.fromcache = fromcache;
-            this.scheme = scheme;
-            this.credentials = credentials;
-            this.retries = 1;
-        }
-
-        AuthInfo(boolean fromcache,
-                 String scheme,
-                 PasswordAuthentication credentials,
-                 CacheEntry ca) {
-            this(fromcache, scheme, credentials);
-            assert credentials == null || (ca != null && ca.value == null);
-            cacheEntry = ca;
-        }
-    }
-
-    @Override
-    public HttpRequestImpl response(HttpResponseImpl r) throws IOException {
-        Cache cache = getCache(r.request);
-        int status = r.statusCode();
-        HttpHeaders hdrs = r.headers();
-        HttpRequestImpl req = r.request();
-
-        if (status != UNAUTHORIZED && status != PROXY_UNAUTHORIZED) {
-            // check if any authentication succeeded for first time
-            if (req.exchange.serverauth != null && !req.exchange.serverauth.fromcache) {
-                AuthInfo au = req.exchange.serverauth;
-                cache.store(au.scheme, req.uri(), false, au.credentials);
-            }
-            if (req.exchange.proxyauth != null && !req.exchange.proxyauth.fromcache) {
-                AuthInfo au = req.exchange.proxyauth;
-                cache.store(au.scheme, req.uri(), false, au.credentials);
-            }
-            return null;
-        }
-
-        boolean proxy = status == PROXY_UNAUTHORIZED;
-        String authname = proxy ? "Proxy-Authenticate" : "WWW-Authenticate";
-        String authval = hdrs.firstValue(authname).orElseThrow(() -> {
-            return new IOException("Invalid auth header");
-        });
-        HeaderParser parser = new HeaderParser(authval);
-        String scheme = parser.findKey(0);
-
-        // TODO: Need to generalise from Basic only. Delegate to a provider class etc.
-
-        if (!scheme.equalsIgnoreCase("Basic")) {
-            return null;   // error gets returned to app
-        }
-
-        String realm = parser.findValue("realm");
-        AuthInfo au = proxy ? req.exchange.proxyauth : req.exchange.serverauth;
-        if (au == null) {
-            PasswordAuthentication pw = getCredentials(authval, proxy, req);
-            if (pw == null) {
-                throw new IOException("No credentials provided");
-            }
-            // No authentication in request. Get credentials from user
-            au = new AuthInfo(false, "Basic", pw);
-            if (proxy)
-                req.exchange.proxyauth = au;
-            else
-                req.exchange.serverauth = au;
-            addBasicCredentials(req, proxy, pw);
-            return req;
-        } else if (au.retries > retry_limit) {
-            throw new IOException("too many authentication attempts");
-        } else {
-            // we sent credentials, but they were rejected
-            if (au.fromcache) {
-                cache.remove(au.cacheEntry);
-            }
-            // try again
-            au.credentials = getCredentials(authval, proxy, req);
-            addBasicCredentials(req, proxy, au.credentials);
-            au.retries++;
-            return req;
-        }
-    }
-
-    static final HashMap<HttpClientImpl,Cache> caches = new HashMap<>();
-
-    static synchronized Cache getCache(HttpRequestImpl req) {
-        HttpClientImpl client = req.client();
-        Cache c = caches.get(client);
-        if (c == null) {
-            c = new Cache();
-            caches.put(client, c);
-        }
-        return c;
-    }
-
-    static class Cache {
-        final LinkedList<CacheEntry> entries = new LinkedList<>();
-
-        synchronized CacheEntry get(URI uri, boolean proxy) {
-            for (CacheEntry entry : entries) {
-                if (entry.equalsKey(uri, proxy)) {
-                    return entry;
-                }
-            }
-            return null;
-        }
-
-        synchronized void remove(String authscheme, URI domain, boolean proxy) {
-            for (CacheEntry entry : entries) {
-                if (entry.equalsKey(domain, proxy)) {
-                    entries.remove(entry);
-                }
-            }
-        }
-
-        synchronized void remove(CacheEntry entry) {
-            entries.remove(entry);
-        }
-
-        synchronized void store(String authscheme,
-                                URI domain,
-                                boolean proxy,
-                                PasswordAuthentication value) {
-            remove(authscheme, domain, proxy);
-            entries.add(new CacheEntry(authscheme, domain, proxy, value));
-        }
-    }
-
-    static class CacheEntry {
-        final String root;
-        final String scheme;
-        final boolean proxy;
-        final PasswordAuthentication value;
-
-        CacheEntry(String authscheme,
-                   URI uri,
-                   boolean proxy,
-                   PasswordAuthentication value) {
-            this.scheme = authscheme;
-            this.root = uri.resolve(".").toString(); // remove extraneous components
-            this.proxy = proxy;
-            this.value = value;
-        }
-
-        public PasswordAuthentication value() {
-            return value;
-        }
-
-        public boolean equalsKey(URI uri, boolean proxy) {
-            if (this.proxy != proxy) {
-                return false;
-            }
-            String other = uri.toString();
-            return other.startsWith(root);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/BufferHandler.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-/**
- * Implemented by buffer pools. A buffer pool has a current buffer size
- * (number of bytes in each buffer) which may increase over time.
- */
-interface BufferHandler {
-
-    default ByteBuffer getBuffer() {
-        return getBuffer(-1);
-    }
-
-    void setMinBufferSize(int size);
-
-    /**
-     * size == -1 means return any sized buffer. Any other value means
-     * @param size
-     * @return
-     */
-    ByteBuffer getBuffer(int size);
-
-    void returnBuffer(ByteBuffer buffer);
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ByteBufferConsumer.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.function.Supplier;
-
-/**
- * Takes a List<ByteBuffer> which is assumed to contain at least one HTTP/2
- * frame and allows it to be processed supplying bytes, ints, shorts, byte[] etc.
- * from the list. As each ByteBuffer is consumed it is removed from the List<>.
- *
- * NOTE. shorts and bytes returned are UNSIGNED ints
- *
- * When finished processing the frame, the List may be empty or may contain
- * partially read or unread ByteBuffers. A new ByteBufferConsumer can be
- * created with the List<>
- */
-class ByteBufferConsumer {
-
-    ByteBuffer currentBuffer;
-
-    final List<ByteBuffer> buffers;
-    final ListIterator<ByteBuffer> iterator;
-    final Supplier<ByteBuffer> newBufferSupplier;
-
-    ByteBufferConsumer(List<ByteBuffer> buffers,
-                       Supplier<ByteBuffer> newBufferSupplier) {
-        this.buffers = buffers;
-        this.newBufferSupplier = newBufferSupplier;
-        this.iterator = buffers.listIterator();
-        if (!iterator.hasNext()) {
-            throw new IllegalArgumentException("Empty buffer list");
-        }
-        currentBuffer = iterator.next();
-    }
-
-    private void dump() {
-        int l = 0;
-        System.err.printf("ByteBufferConsumer:\n");
-        for (ByteBuffer buf : buffers) {
-            System.err.printf("\t%s\n", buf.toString());
-            l+= buf.remaining();
-        }
-        System.err.printf("BBC contains %d bytes\n", l);
-    }
-
-    private synchronized ByteBuffer getBuffer(boolean exception) throws IOException {
-        while (currentBuffer == null || !currentBuffer.hasRemaining()) {
-            if (currentBuffer != null) {
-                iterator.remove();
-            }
-            if (!iterator.hasNext()) {
-                currentBuffer = null;
-                if (exception) {
-                    throw new IOException ("Connection closed unexpectedly");
-                }
-                return null;
-            }
-            currentBuffer = iterator.next();
-        }
-        return currentBuffer;
-    }
-
-    // call this to check if the data has all been consumed
-
-    public boolean consumed() {
-        try {
-            return getBuffer(false) == null;
-        } catch (IOException e) {
-            /* CAN'T HAPPEN */
-            throw new InternalError();
-        }
-    }
-
-    public int getByte() throws IOException {
-        // TODO: what to do if connection is closed. Throw NPE?
-        ByteBuffer buf = getBuffer(true);
-        return buf.get() & 0xff;
-    }
-
-    public byte[] getBytes(int n) throws IOException {
-        return getBytes(n, null);
-    }
-
-    public byte[] getBytes(int n, byte[] buf) throws IOException {
-        if (buf == null) {
-            buf = new byte[n];
-        } else if (buf.length < n) {
-            throw new IllegalArgumentException("getBytes: buffer too small");
-        }
-        int offset = 0;
-        while (n > 0) {
-            ByteBuffer b = getBuffer(true);
-            int length = Math.min(n, b.remaining());
-            b.get(buf, offset, length);
-            offset += length;
-            n -= length;
-        }
-        return buf;
-    }
-
-    public int getShort() throws IOException {
-        ByteBuffer buf = getBuffer(true);
-        int rem = buf.remaining();
-        if (rem >= 2) {
-            return buf.getShort() & 0xffff;
-        }
-        // Slow path. Not common
-        int val = 0;
-        val = (val << 8) + getByte();
-        val = (val << 8) + getByte();
-        return val;
-    }
-
-    public int getInt() throws IOException {
-        ByteBuffer buf = getBuffer(true);
-        int rem = buf.remaining();
-        if (rem >= 4) {
-            return buf.getInt();
-        }
-        // Slow path. Not common
-        int val = 0;
-        for (int nbytes = 0; nbytes < 4; nbytes++) {
-            val = (val << 8) + getByte();
-        }
-        return val;
-    }
-
-    private static final ByteBuffer[] EMPTY = new ByteBuffer[0];
-
-    /**
-     * Extracts whatever number of ByteBuffers from list to get required number
-     * of bytes. Any remaining buffers are 'tidied up' so reading can continue.
-     */
-    public ByteBuffer[] getBuffers(int bytecount) throws IOException {
-        LinkedList<ByteBuffer> l = new LinkedList<>();
-        while (bytecount > 0) {
-            ByteBuffer buffer = getBuffer(true);
-            int remaining = buffer.remaining();
-            if (remaining > bytecount) {
-                int difference = remaining - bytecount;
-                // split
-                ByteBuffer newb = newBufferSupplier.get();
-                newb.clear();
-                int limit = buffer.limit();
-                buffer.limit(limit - difference);
-                newb.put(buffer);
-                newb.flip();
-                buffer.limit(limit);
-                l.add(newb);
-                bytecount = 0;
-            } else {
-                l.add(buffer);
-                currentBuffer = null;
-                iterator.remove();
-                bytecount -= remaining;
-            }
-        }
-        return l.toArray(EMPTY);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ByteBufferGenerator.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/**
- * Manages a ByteBuffer[] for writing frames into for output. The last
- * ByteBuffer in the list is always unflipped (able to receive more bytes for
- * sending) until getBufferArray() is called, which calls finish().
- *
- * This allows multiple frames to be written to the same BBG.
- *
- * Buffers added with addByteBuffer() must be already flipped.
- */
-class ByteBufferGenerator {
-
-    ByteBuffer currentBuffer;
-    // source is assumed to always return the same sized buffer
-    final BufferHandler pool;
-    final ArrayList<ByteBuffer> buflist;
-    final int bufsize;
-    boolean finished;
-
-    ByteBufferGenerator(BufferHandler pool) {
-        this.buflist = new ArrayList<>();
-        this.pool = pool;
-        this.currentBuffer = pool.getBuffer();
-        this.bufsize = currentBuffer.capacity();
-    }
-
-    private static final ByteBuffer[] EMPTY = new ByteBuffer[0];
-
-    public ByteBuffer[] getBufferArray() {
-        finish();
-        return buflist.toArray(EMPTY);
-    }
-
-    public ArrayList<ByteBuffer> getBufferList() {
-        finish();
-        return buflist;
-    }
-
-    private synchronized void finish() {
-        if (finished) {
-            return;
-        }
-        finished = true;
-        currentBuffer.flip();
-        if (currentBuffer.hasRemaining()) {
-            buflist.add(currentBuffer);
-        } else {
-            pool.returnBuffer(currentBuffer);
-        }
-    }
-
-    // only used for SettingsFrame: offset is number of bytes to
-    // ignore at start (we only want the payload of the settings frame)
-    public byte[] asByteArray(int offset) {
-        ByteBuffer[] bufs = getBufferArray();
-        int size = 0;
-        for (ByteBuffer buf : bufs) {
-            size += buf.remaining();
-        }
-        byte[] bytes = new byte[size-offset];
-        int pos = 0;
-        for (ByteBuffer buf : bufs) {
-            int rem = buf.remaining();
-            int ignore = Math.min(rem, offset);
-            buf.position(buf.position()+ignore);
-            rem -= ignore;
-            offset -= ignore;
-            buf.get(bytes, pos, rem);
-            pos += rem;
-        }
-        return bytes;
-    }
-
-    ByteBuffer getBuffer(long n) {
-        if (currentBuffer.remaining() < n) {
-            getNewBuffer();
-            if (n > currentBuffer.capacity()) {
-                throw new IllegalArgumentException("requested buffer too large");
-            }
-        }
-        return currentBuffer;
-    }
-
-    void getNewBuffer() {
-        currentBuffer.flip();
-        if (currentBuffer.hasRemaining()) {
-            buflist.add(currentBuffer);
-        } else {
-            pool.returnBuffer(currentBuffer);
-        }
-        currentBuffer = pool.getBuffer();
-    }
-
-    void addByteBuffer(ByteBuffer buf) {
-        getNewBuffer();
-        buflist.add(buf);
-    }
-
-    void addPadding(int length) {
-        while (length > 0) {
-            int n = Math.min(length, bufsize);
-            ByteBuffer b = getBuffer(n);
-            // TODO: currently zeroed?
-            b.position(b.position() + n);
-            length -= n;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/CharsetToolkit.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-// The purpose of this class is to separate charset-related tasks from the main
-// WebSocket logic, simplifying where possible.
-//
-//     * Coders hide the differences between coding and flushing stages on the
-//       API level
-//     * Verifier abstracts the way the verification is performed
-//       (spoiler: it's a decoding into a throw-away buffer)
-//
-// Coding methods throw exceptions instead of returning coding result denoting
-// errors, since any kind of handling and recovery is not expected.
-final class CharsetToolkit {
-
-    private CharsetToolkit() { }
-
-    static final class Verifier {
-
-        private final CharsetDecoder decoder = UTF_8.newDecoder();
-        // A buffer used to check validity of UTF-8 byte stream by decoding it.
-        // The contents of this buffer are never used.
-        // The size is arbitrary, though it should probably be chosen from the
-        // performance perspective since it affects the total number of calls to
-        // decoder.decode() and amount of work in each of these calls
-        private final CharBuffer blackHole = CharBuffer.allocate(1024);
-
-        void verify(ByteBuffer in, boolean endOfInput)
-                throws CharacterCodingException {
-            while (true) {
-                // Since decoder.flush() cannot produce an error, it's not
-                // helpful for verification. Therefore this step is skipped.
-                CoderResult r = decoder.decode(in, blackHole, endOfInput);
-                if (r.isOverflow()) {
-                    blackHole.clear();
-                } else if (r.isUnderflow()) {
-                    break;
-                } else if (r.isError()) {
-                    r.throwException();
-                } else {
-                    // Should not happen
-                    throw new InternalError();
-                }
-            }
-        }
-
-        Verifier reset() {
-            decoder.reset();
-            return this;
-        }
-    }
-
-    static final class Encoder {
-
-        private final CharsetEncoder encoder = UTF_8.newEncoder();
-        private boolean coding = true;
-
-        CoderResult encode(CharBuffer in, ByteBuffer out, boolean endOfInput)
-                throws CharacterCodingException {
-
-            if (coding) {
-                CoderResult r = encoder.encode(in, out, endOfInput);
-                if (r.isOverflow()) {
-                    return r;
-                } else if (r.isUnderflow()) {
-                    if (endOfInput) {
-                        coding = false;
-                    } else {
-                        return r;
-                    }
-                } else if (r.isError()) {
-                    r.throwException();
-                } else {
-                    // Should not happen
-                    throw new InternalError();
-                }
-            }
-            assert !coding;
-            return encoder.flush(out);
-        }
-
-        Encoder reset() {
-            coding = true;
-            encoder.reset();
-            return this;
-        }
-    }
-
-    static CharBuffer decode(ByteBuffer in) throws CharacterCodingException {
-        return UTF_8.newDecoder().decode(in);
-    }
-
-    static final class Decoder {
-
-        private final CharsetDecoder decoder = UTF_8.newDecoder();
-        private boolean coding = true; // Either coding or flushing
-
-        CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)
-                throws CharacterCodingException {
-
-            if (coding) {
-                CoderResult r = decoder.decode(in, out, endOfInput);
-                if (r.isOverflow()) {
-                    return r;
-                } else if (r.isUnderflow()) {
-                    if (endOfInput) {
-                        coding = false;
-                    } else {
-                        return r;
-                    }
-                } else if (r.isError()) {
-                    r.throwException();
-                } else {
-                    // Should not happen
-                    throw new InternalError();
-                }
-            }
-            assert !coding;
-            return decoder.flush(out);
-        }
-
-        Decoder reset() {
-            coding = true;
-            decoder.reset();
-            return this;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ConnectionPool.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Objects;
-
-/**
- * Http 1.1 connection pool.
- */
-class ConnectionPool {
-
-    static final long KEEP_ALIVE = Utils.getIntegerNetProperty(
-            "java.net.httpclient.keepalive.timeout", 1200); // seconds
-
-    // Pools of idle connections
-
-    final HashMap<CacheKey,LinkedList<HttpConnection>> plainPool;
-    final HashMap<CacheKey,LinkedList<HttpConnection>> sslPool;
-    CacheCleaner cleaner;
-
-    /**
-     * Entries in connection pool are keyed by destination address and/or
-     * proxy address:
-     * case 1: plain TCP not via proxy (destination only)
-     * case 2: plain TCP via proxy (proxy only)
-     * case 3: SSL not via proxy (destination only)
-     * case 4: SSL over tunnel (destination and proxy)
-     */
-    static class CacheKey {
-        final InetSocketAddress proxy;
-        final InetSocketAddress destination;
-
-        CacheKey(InetSocketAddress destination, InetSocketAddress proxy) {
-            this.proxy = proxy;
-            this.destination = destination;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            final CacheKey other = (CacheKey) obj;
-            if (!Objects.equals(this.proxy, other.proxy)) {
-                return false;
-            }
-            if (!Objects.equals(this.destination, other.destination)) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(proxy, destination);
-        }
-    }
-
-    static class ExpiryEntry {
-        final HttpConnection connection;
-        final long expiry; // absolute time in seconds of expiry time
-        ExpiryEntry(HttpConnection connection, long expiry) {
-            this.connection = connection;
-            this.expiry = expiry;
-        }
-    }
-
-    final LinkedList<ExpiryEntry> expiryList;
-
-    /**
-     * There should be one of these per HttpClient.
-     */
-    ConnectionPool() {
-        plainPool = new HashMap<>();
-        sslPool = new HashMap<>();
-        expiryList = new LinkedList<>();
-        cleaner = new CacheCleaner();
-    }
-
-    void start() {
-        cleaner.start();
-    }
-
-    static CacheKey cacheKey(InetSocketAddress destination,
-                             InetSocketAddress proxy) {
-        return new CacheKey(destination, proxy);
-    }
-
-    synchronized HttpConnection getConnection(boolean secure,
-                                              InetSocketAddress addr,
-                                              InetSocketAddress proxy) {
-        CacheKey key = new CacheKey(addr, proxy);
-        HttpConnection c = secure ? findConnection(key, sslPool)
-                                  : findConnection(key, plainPool);
-        //System.out.println ("getConnection returning: " + c);
-        return c;
-    }
-
-    /**
-     * Returns the connection to the pool.
-     *
-     * @param conn
-     */
-    synchronized void returnToPool(HttpConnection conn) {
-        if (conn instanceof PlainHttpConnection) {
-            putConnection(conn, plainPool);
-        } else {
-            putConnection(conn, sslPool);
-        }
-        addToExpiryList(conn);
-        //System.out.println("Return to pool: " + conn);
-    }
-
-    private HttpConnection
-    findConnection(CacheKey key,
-                   HashMap<CacheKey,LinkedList<HttpConnection>> pool) {
-        LinkedList<HttpConnection> l = pool.get(key);
-        if (l == null || l.size() == 0) {
-            return null;
-        } else {
-            HttpConnection c = l.removeFirst();
-            removeFromExpiryList(c);
-            return c;
-        }
-    }
-
-    /* called from cache cleaner only  */
-    private void
-    removeFromPool(HttpConnection c,
-                   HashMap<CacheKey,LinkedList<HttpConnection>> pool) {
-        //System.out.println("cacheCleaner removing: " + c);
-        LinkedList<HttpConnection> l = pool.get(c.cacheKey());
-        assert l != null;
-        boolean wasPresent = l.remove(c);
-        assert wasPresent;
-    }
-
-    private void
-    putConnection(HttpConnection c,
-                  HashMap<CacheKey,LinkedList<HttpConnection>> pool) {
-        CacheKey key = c.cacheKey();
-        LinkedList<HttpConnection> l = pool.get(key);
-        if (l == null) {
-            l = new LinkedList<>();
-            pool.put(key, l);
-        }
-        l.add(c);
-    }
-
-    // only runs while entries exist in cache
-
-    class CacheCleaner extends Thread {
-
-        volatile boolean stopping;
-
-        CacheCleaner() {
-            super(null, null, "HTTP-Cache-cleaner", 0, false);
-            setDaemon(true);
-        }
-
-        synchronized boolean stopping() {
-            return stopping;
-        }
-
-        synchronized void stopCleaner() {
-            stopping = true;
-        }
-
-        @Override
-        public void run() {
-            while (!stopping()) {
-                try {
-                    Thread.sleep(3000);
-                } catch (InterruptedException e) {}
-                cleanCache();
-            }
-        }
-    }
-
-    synchronized void removeFromExpiryList(HttpConnection c) {
-        if (c == null) {
-            return;
-        }
-        ListIterator<ExpiryEntry> li = expiryList.listIterator();
-        while (li.hasNext()) {
-            ExpiryEntry e = li.next();
-            if (e.connection.equals(c)) {
-                li.remove();
-                return;
-            }
-        }
-        if (expiryList.isEmpty()) {
-            cleaner.stopCleaner();
-        }
-    }
-
-    private void cleanCache() {
-        long now = System.currentTimeMillis() / 1000;
-        LinkedList<HttpConnection> closelist = new LinkedList<>();
-
-        synchronized (this) {
-            ListIterator<ExpiryEntry> li = expiryList.listIterator();
-            while (li.hasNext()) {
-                ExpiryEntry entry = li.next();
-                if (entry.expiry <= now) {
-                    li.remove();
-                    HttpConnection c = entry.connection;
-                    closelist.add(c);
-                    if (c instanceof PlainHttpConnection) {
-                        removeFromPool(c, plainPool);
-                    } else {
-                        removeFromPool(c, sslPool);
-                    }
-                }
-            }
-        }
-        for (HttpConnection c : closelist) {
-            //System.out.println ("KAC: closing " + c);
-            c.close();
-        }
-    }
-
-    private synchronized void addToExpiryList(HttpConnection conn) {
-        long now = System.currentTimeMillis() / 1000;
-        long then = now + KEEP_ALIVE;
-
-        if (expiryList.isEmpty())
-            cleaner = new CacheCleaner();
-
-        ListIterator<ExpiryEntry> li = expiryList.listIterator();
-        while (li.hasNext()) {
-            ExpiryEntry entry = li.next();
-
-            if (then > entry.expiry) {
-                li.previous();
-                // insert here
-                li.add(new ExpiryEntry(conn, then));
-                return;
-            }
-        }
-        // first element of list
-        expiryList.add(new ExpiryEntry(conn, then));
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ContinuationFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-class ContinuationFrame extends HeaderFrame {
-
-    public static final int TYPE = 0x9;
-
-    ContinuationFrame() {
-        type = TYPE;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        headerBlocks = bc.getBuffers(length);
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        for (int i=0; i<headerBlocks.length; i++) {
-            bg.addByteBuffer(headerBlocks[i]);
-        }
-    }
-
-    @Override
-    public boolean endHeaders() {
-        return getFlag(END_HEADERS);
-    }
-
-    @Override
-    void computeLength() {
-        length = headerLength;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/CookieFilter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.CookieManager;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-class CookieFilter implements HeaderFilter {
-
-    final HttpClientImpl client;
-    final CookieManager cookieMan;
-
-    CookieFilter(HttpClientImpl client) {
-        this.client = client;
-        this.cookieMan = client.cookieManager().orElseThrow(
-                () -> new IllegalArgumentException("no cookie manager"));
-    }
-
-    @Override
-    public void request(HttpRequestImpl r) throws IOException {
-        Map<String,List<String>> userheaders, cookies;
-        userheaders = r.getUserHeaders().map();
-        cookies = cookieMan.get(r.uri(), userheaders);
-        // add the returned cookies
-        HttpHeadersImpl systemHeaders = r.getSystemHeaders();
-        Set<String> keys = cookies.keySet();
-        for (String hdrname : keys) {
-            List<String> vals = cookies.get(hdrname);
-            for (String val : vals) {
-                systemHeaders.addHeader(hdrname, val);
-            }
-        }
-    }
-
-    @Override
-    public HttpRequestImpl response(HttpResponseImpl r) throws IOException {
-        HttpHeaders hdrs = r.headers();
-        cookieMan.put(r.uri(), hdrs.map());
-        return null;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/DataFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class DataFrame extends Http2Frame {
-
-    public final static int TYPE = 0x0;
-
-    DataFrame() {
-        type = TYPE;
-    }
-
-    // Flags
-    public static final int END_STREAM = 0x1;
-    public static final int PADDED = 0x8;
-
-    int padLength;
-    int dataLength;
-    ByteBuffer[] data;
-
-    public void setData(ByteBuffer[] data) {
-        this.data = data;
-        setDataLength();
-    }
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-        case END_STREAM:
-            return "END_STREAM";
-        case PADDED:
-            return "PADDED";
-        }
-        return super.flagAsString(flag);
-    }
-
-    public synchronized void setData(ByteBuffer data) {
-        ByteBuffer[] bb;
-        if (data == null) {
-            bb = new ByteBuffer[0];
-        } else {
-            bb = new ByteBuffer[1];
-            bb[0] = data;
-        }
-        setData(bb);
-    }
-
-    public synchronized ByteBuffer[] getData() {
-        return data;
-    }
-
-    private void setDataLength() {
-        int len = 0;
-        for (ByteBuffer buf : data) {
-            len += buf.remaining();
-        }
-        dataLength = len;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if ((flags & PADDED) != 0) {
-            padLength = bc.getByte();
-            dataLength = length - (padLength + 1);
-        } else {
-            dataLength = length;
-        }
-        data = bc.getBuffers(dataLength);
-    }
-
-    int getPadLength() {
-        return padLength;
-    }
-
-    int getDataLength() {
-        return dataLength;
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        if ((flags & PADDED) != 0) {
-            ByteBuffer buf = bg.getBuffer(1);
-            buf.put((byte)getPadLength());
-        }
-        for (int i=0; i<data.length; i++) {
-            bg.addByteBuffer(data[i]);
-        }
-        if ((flags & PADDED) != 0) {
-            bg.addPadding(padLength);
-        }
-    }
-
-    @Override
-    void computeLength() {
-        length = dataLength;
-        if ((flags & PADDED) != 0) {
-            length += (1 + padLength);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ErrorFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-abstract class ErrorFrame extends Http2Frame {
-
-    // error codes
-    public static final int NO_ERROR = 0x0;
-    public static final int PROTOCOL_ERROR = 0x1;
-    public static final int INTERNAL_ERROR = 0x2;
-    public static final int FLOW_CONTROL_ERROR = 0x3;
-    public static final int SETTINGS_TIMEOUT = 0x4;
-    public static final int STREAM_CLOSED = 0x5;
-    public static final int FRAME_SIZE_ERROR = 0x6;
-    public static final int REFUSED_STREAM = 0x7;
-    public static final int CANCEL = 0x8;
-    public static final int COMPRESSION_ERROR = 0x9;
-    public static final int CONNECT_ERROR = 0xa;
-    public static final int ENHANCE_YOUR_CALM = 0xb;
-    public static final int INADEQUATE_SECURITY = 0xc;
-    public static final int HTTP_1_1_REQUIRED = 0xd;
-    static final int LAST_ERROR = 0xd;
-
-    static final String[] errorStrings = {
-        "Not an error",
-        "Protocol error",
-        "Internal error",
-        "Flow control error",
-        "Settings timeout",
-        "Stream is closed",
-        "Frame size error",
-        "Stream not processed",
-        "Stream cancelled",
-        "Compression state not updated",
-        "TCP Connection error on CONNECT",
-        "Processing capacity exceeded",
-        "Negotiated TLS parameters not acceptable",
-        "Use HTTP/1.1 for request"
-    };
-
-    public static String stringForCode(int code) {
-        if (code < 0)
-            throw new IllegalArgumentException();
-
-        if (code > LAST_ERROR) {
-            return "Error: " + Integer.toString(code);
-        } else {
-            return errorStrings[code];
-        }
-    }
-
-    int errorCode;
-
-    @Override
-    public String toString() {
-        return super.toString() + " Error: " + stringForCode(errorCode);
-    }
-
-    public int getErrorCode() {
-        return this.errorCode;
-    }
-
-    public void setErrorCode(int errorCode) {
-        this.errorCode = errorCode;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.net.SocketPermission;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLPermission;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * One request/response exchange (handles 100/101 intermediate response also).
- * depth field used to track number of times a new request is being sent
- * for a given API request. If limit exceeded exception is thrown.
- *
- * Security check is performed here:
- * - uses AccessControlContext captured at API level
- * - checks for appropriate URLPermission for request
- * - if permission allowed, grants equivalent SocketPermission to call
- * - in case of direct HTTP proxy, checks additionally for access to proxy
- *    (CONNECT proxying uses its own Exchange, so check done there)
- *
- */
-class Exchange {
-
-    final HttpRequestImpl request;
-    final HttpClientImpl client;
-    ExchangeImpl exchImpl;
-    HttpResponseImpl response;
-    final List<SocketPermission> permissions = new LinkedList<>();
-    AccessControlContext acc;
-    boolean upgrading; // to HTTP/2
-
-    Exchange(HttpRequestImpl request) {
-        this.request = request;
-        this.upgrading = false;
-        this.client = request.client();
-    }
-
-    /* If different AccessControlContext to be used  */
-    Exchange(HttpRequestImpl request, AccessControlContext acc) {
-        this.request = request;
-        this.acc = acc;
-        this.upgrading = false;
-        this.client = request.client();
-    }
-
-    public HttpRequestImpl request() {
-        return request;
-    }
-
-    public HttpResponseImpl response() throws IOException, InterruptedException {
-        response = responseImpl(null);
-        return response;
-    }
-
-    public void cancel() {
-        if (exchImpl != null)
-            exchImpl.cancel();
-    }
-
-    public void h2Upgrade() {
-        upgrading = true;
-        request.setH2Upgrade();
-    }
-
-    static final SocketPermission[] SOCKET_ARRAY = new SocketPermission[0];
-
-    HttpResponseImpl responseImpl(HttpConnection connection)
-        throws IOException, InterruptedException
-    {
-        if (acc == null) {
-            acc = request.getAccessControlContext();
-        }
-        SecurityException e = securityCheck(acc);
-        if (e != null)
-            throw e;
-
-        if (permissions.size() > 0) {
-            try {
-                return AccessController.doPrivileged(
-                        (PrivilegedExceptionAction<HttpResponseImpl>)() ->
-                             responseImpl0(connection),
-                        null,
-                        permissions.toArray(SOCKET_ARRAY));
-            } catch (Throwable ee) {
-                if (ee instanceof PrivilegedActionException) {
-                    ee = ee.getCause();
-                }
-                if (ee instanceof IOException)
-                    throw (IOException)ee;
-                else
-                    throw new RuntimeException(ee); // TODO: fix
-            }
-        } else {
-            return responseImpl0(connection);
-        }
-    }
-
-    private HttpResponseImpl responseImpl0(HttpConnection connection)
-        throws IOException, InterruptedException
-    {
-        exchImpl = ExchangeImpl.get(this, connection);
-        if (request.expectContinue()) {
-            request.addSystemHeader("Expect", "100-Continue");
-            exchImpl.sendHeadersOnly();
-            HttpResponseImpl resp = exchImpl.getResponse();
-            Utils.logResponse(resp);
-            if (resp.statusCode() != 100) {
-                return resp;
-            }
-            exchImpl.sendBody();
-            return exchImpl.getResponse();
-        } else {
-            exchImpl.sendRequest();
-            HttpResponseImpl resp = exchImpl.getResponse();
-            Utils.logResponse(resp);
-            return checkForUpgrade(resp, exchImpl);
-        }
-    }
-
-    // Completed HttpResponse will be null if response succeeded
-    // will be a non null responseAsync if expect continue returns an error
-
-    public CompletableFuture<HttpResponseImpl> responseAsync(Void v) {
-        return responseAsyncImpl(null);
-    }
-
-    CompletableFuture<HttpResponseImpl> responseAsyncImpl(HttpConnection connection) {
-        if (acc == null) {
-            acc = request.getAccessControlContext();
-        }
-        SecurityException e = securityCheck(acc);
-        if (e != null) {
-            return CompletableFuture.failedFuture(e);
-        }
-        if (permissions.size() > 0) {
-            return AccessController.doPrivileged(
-                    (PrivilegedAction<CompletableFuture<HttpResponseImpl>>)() ->
-                        responseAsyncImpl0(connection),
-                    null,
-                    permissions.toArray(SOCKET_ARRAY));
-        } else {
-            return responseAsyncImpl0(connection);
-        }
-    }
-
-    CompletableFuture<HttpResponseImpl> responseAsyncImpl0(HttpConnection connection) {
-        try {
-            exchImpl = ExchangeImpl.get(this, connection);
-        } catch (IOException | InterruptedException e) {
-            return CompletableFuture.failedFuture(e);
-        }
-        if (request.expectContinue()) {
-            request.addSystemHeader("Expect", "100-Continue");
-            return exchImpl.sendHeadersAsync()
-                    .thenCompose(exchImpl::getResponseAsync)
-                    .thenCompose((HttpResponseImpl r1) -> {
-                        int rcode = r1.statusCode();
-                        CompletableFuture<HttpResponseImpl> cf =
-                                checkForUpgradeAsync(r1, exchImpl);
-                        if (cf != null)
-                            return cf;
-                        if (rcode == 100) {
-                            return exchImpl.sendBodyAsync()
-                                .thenCompose(exchImpl::getResponseAsync)
-                                .thenApply((r) -> {
-                                    Utils.logResponse(r);
-                                    return r;
-                                });
-                        } else {
-                            Exchange.this.response = r1;
-                            Utils.logResponse(r1);
-                            return CompletableFuture.completedFuture(r1);
-                        }
-                    });
-        } else {
-            return exchImpl
-                .sendRequestAsync()
-                .thenCompose(exchImpl::getResponseAsync)
-                .thenCompose((HttpResponseImpl r1) -> {
-                    int rcode = r1.statusCode();
-                    CompletableFuture<HttpResponseImpl> cf =
-                            checkForUpgradeAsync(r1, exchImpl);
-                    if (cf != null) {
-                        return cf;
-                    } else {
-                        Exchange.this.response = r1;
-                        Utils.logResponse(r1);
-                        return CompletableFuture.completedFuture(r1);
-                    }
-                })
-                .thenApply((HttpResponseImpl response) -> {
-                    this.response = response;
-                    Utils.logResponse(response);
-                    return response;
-                });
-        }
-    }
-
-    // if this response was received in reply to an upgrade
-    // then create the Http2Connection from the HttpConnection
-    // initialize it and wait for the real response on a newly created Stream
-
-    private CompletableFuture<HttpResponseImpl>
-    checkForUpgradeAsync(HttpResponseImpl resp,
-                         ExchangeImpl ex) {
-        int rcode = resp.statusCode();
-        if (upgrading && (rcode == 101)) {
-            Http1Exchange e = (Http1Exchange)ex;
-            // check for 101 switching protocols
-            return e.responseBodyAsync(HttpResponse.ignoreBody())
-                .thenCompose((Void v) ->
-                     Http2Connection.createAsync(e.connection(),
-                                                 client.client2(),
-                                                 this)
-                        .thenCompose((Http2Connection c) -> {
-                            c.putConnection();
-                            Stream s = c.getStream(1);
-                            exchImpl = s;
-                            return s.getResponseAsync(null);
-                        })
-                );
-        }
-        return CompletableFuture.completedFuture(resp);
-    }
-
-    private HttpResponseImpl checkForUpgrade(HttpResponseImpl resp,
-                                             ExchangeImpl ex)
-        throws IOException, InterruptedException
-    {
-        int rcode = resp.statusCode();
-        if (upgrading && (rcode == 101)) {
-            Http1Exchange e = (Http1Exchange) ex;
-            // must get connection from Http1Exchange
-            e.responseBody(HttpResponse.ignoreBody(), false);
-            Http2Connection h2con = new Http2Connection(e.connection(),
-                                                        client.client2(),
-                                                        this);
-            h2con.putConnection();
-            Stream s = h2con.getStream(1);
-            exchImpl = s;
-            return s.getResponse();
-        }
-        return resp;
-    }
-
-
-    <T> T responseBody(HttpResponse.BodyProcessor<T> processor) {
-        try {
-            return exchImpl.responseBody(processor);
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-
-
-    <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
-        return exchImpl.responseBodyAsync(processor);
-    }
-
-    private URI getURIForSecurityCheck() {
-        URI u;
-        String method = request.method();
-        InetSocketAddress authority = request.authority();
-        URI uri = request.uri();
-
-        // CONNECT should be restricted at API level
-        if (method.equalsIgnoreCase("CONNECT")) {
-            try {
-                u = new URI("socket",
-                             null,
-                             authority.getHostString(),
-                             authority.getPort(),
-                             null,
-                             null,
-                             null);
-            } catch (URISyntaxException e) {
-                throw new InternalError(e); // shouldn't happen
-            }
-        } else {
-            u = uri;
-        }
-        return u;
-    }
-
-    /**
-     * Do the security check and return any exception.
-     * Return null if no check needed or passes.
-     *
-     * Also adds any generated permissions to the "permissions" list.
-     */
-    private SecurityException securityCheck(AccessControlContext acc) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm == null) {
-            return null;
-        }
-
-        String method = request.method();
-        HttpHeaders userHeaders = request.getUserHeaders();
-        URI u = getURIForSecurityCheck();
-        URLPermission p = Utils.getPermission(u, method, userHeaders.map());
-
-        try {
-            assert acc != null;
-            sm.checkPermission(p, acc);
-            permissions.add(getSocketPermissionFor(u));
-        } catch (SecurityException e) {
-            return e;
-        }
-        InetSocketAddress proxy = request.proxy();
-        if (proxy != null) {
-            // may need additional check
-            if (!method.equals("CONNECT")) {
-                // a direct http proxy. Need to check access to proxy
-                try {
-                    u = new URI("socket", null, proxy.getHostString(),
-                        proxy.getPort(), null, null, null);
-                } catch (URISyntaxException e) {
-                    throw new InternalError(e); // shouldn't happen
-                }
-                p = new URLPermission(u.toString(), "CONNECT");
-                try {
-                    sm.checkPermission(p, acc);
-                } catch (SecurityException e) {
-                    permissions.clear();
-                    return e;
-                }
-                String sockperm = proxy.getHostString() +
-                        ":" + Integer.toString(proxy.getPort());
-
-                permissions.add(new SocketPermission(sockperm, "connect,resolve"));
-            }
-        }
-        return null;
-    }
-
-    private static SocketPermission getSocketPermissionFor(URI url) {
-        if (System.getSecurityManager() == null)
-            return null;
-
-        StringBuilder sb = new StringBuilder();
-        String host = url.getHost();
-        sb.append(host);
-        int port = url.getPort();
-        if (port == -1) {
-            String scheme = url.getScheme();
-            if ("http".equals(scheme)) {
-                sb.append(":80");
-            } else { // scheme must be https
-                sb.append(":443");
-            }
-        } else {
-            sb.append(':')
-              .append(Integer.toString(port));
-        }
-        String target = sb.toString();
-        return new SocketPermission(target, "connect");
-    }
-
-    AccessControlContext getAccessControlContext() {
-        return acc;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ExchangeImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.concurrent.CompletableFuture;
-import static java.net.http.HttpClient.Version.HTTP_1_1;
-
-/**
- * Splits request so that headers and body can be sent separately with optional
- * (multiple) responses in between (e.g. 100 Continue). Also request and
- * response always sent/received in different calls.
- *
- * Synchronous and asynchronous versions of each method are provided.
- *
- * Separate implementations of this class exist for HTTP/1.1 and HTTP/2
- *      Http1Exchange   (HTTP/1.1)
- *      Stream          (HTTP/2)
- *
- * These implementation classes are where work is allocated to threads.
- */
-abstract class ExchangeImpl {
-
-    final Exchange exchange;
-
-    ExchangeImpl(Exchange e) {
-        this.exchange = e;
-    }
-
-    /**
-     * Initiates a new exchange and assigns it to a connection if one exists
-     * already. connection usually null.
-     */
-    static ExchangeImpl get(Exchange exchange, HttpConnection connection)
-        throws IOException, InterruptedException
-    {
-        HttpRequestImpl req = exchange.request();
-        if (req.version() == HTTP_1_1) {
-            return new Http1Exchange(exchange, connection);
-        } else {
-            Http2ClientImpl c2 = exchange.request().client().client2(); // TODO: improve
-            HttpRequestImpl request = exchange.request();
-            Http2Connection c = c2.getConnectionFor(request);
-            if (c == null) {
-                // no existing connection. Send request with HTTP 1 and then
-                // upgrade if successful
-                ExchangeImpl ex = new Http1Exchange(exchange, connection);
-                exchange.h2Upgrade();
-                return ex;
-            }
-            return c.createStream(exchange);
-        }
-    }
-
-    /* The following methods have separate HTTP/1.1 and HTTP/2 implementations */
-
-    /**
-     * Sends the request headers only. May block until all sent.
-     */
-    abstract void sendHeadersOnly() throws IOException, InterruptedException;
-
-    /**
-     * Gets response headers by blocking if necessary. This may be an
-     * intermediate response (like 101) or a final response 200 etc.
-     */
-    abstract HttpResponseImpl getResponse() throws IOException;
-
-    /**
-     * Sends a request body after request headers.
-     */
-    abstract void sendBody() throws IOException, InterruptedException;
-
-    /**
-     * Sends the entire request (headers and body) blocking.
-     */
-    abstract void sendRequest() throws IOException, InterruptedException;
-
-    /**
-     * Asynchronous version of sendHeaders().
-     */
-    abstract CompletableFuture<Void> sendHeadersAsync();
-
-    /**
-     * Asynchronous version of getResponse().  Requires void parameter for
-     * CompletableFuture chaining.
-     */
-    abstract CompletableFuture<HttpResponseImpl> getResponseAsync(Void v);
-
-    /**
-     * Asynchronous version of sendBody().
-     */
-    abstract CompletableFuture<Void> sendBodyAsync();
-
-    /**
-     * Cancels a request.  Not currently exposed through API.
-     */
-    abstract void cancel();
-
-    /**
-     * Asynchronous version of sendRequest().
-     */
-    abstract CompletableFuture<Void> sendRequestAsync();
-
-    abstract <T> T responseBody(HttpResponse.BodyProcessor<T> processor)
-        throws IOException;
-
-    /**
-     * Asynchronous version of responseBody().
-     */
-    abstract <T> CompletableFuture<T>
-    responseBodyAsync(HttpResponse.BodyProcessor<T> processor);
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ExecutorWrapper.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.function.Supplier;
-
-/**
- * Wraps the supplied user ExecutorService.
- *
- * 1) when a Security manager set, the correct access control context
- *    is used to execute task
- *
- * 2) memory fence implemented
- */
-class ExecutorWrapper {
-
-    final ExecutorService userExecutor; // the actual executor service used
-    final Executor executor;
-
-    public static ExecutorWrapper wrap(ExecutorService userExecutor) {
-        return new ExecutorWrapper(userExecutor);
-    }
-
-    /**
-     * Returns a dummy ExecutorWrapper which uses the calling thread
-     */
-    public static ExecutorWrapper callingThread() {
-        return new ExecutorWrapper();
-    }
-
-    private ExecutorWrapper(ExecutorService userExecutor) {
-        // used for executing in calling thread
-        this.userExecutor = userExecutor;
-        this.executor = userExecutor;
-    }
-
-    private ExecutorWrapper() {
-        this.userExecutor = null;
-        this.executor = (Runnable command) -> {
-            command.run();
-        };
-    }
-
-    public ExecutorService userExecutor() {
-        return userExecutor;
-    }
-
-    public synchronized void synchronize() {}
-
-    public void execute(Runnable r, Supplier<AccessControlContext> ctxSupplier) {
-        synchronize();
-        Runnable r1 = () -> {
-            try {
-                r.run();
-            } catch (Throwable t) {
-                Log.logError(t);
-            }
-        };
-
-        if (ctxSupplier != null && System.getSecurityManager() != null) {
-            AccessControlContext acc = ctxSupplier.get();
-            if (acc == null) {
-                throw new InternalError();
-            }
-            AccessController.doPrivilegedWithCombiner(
-                (PrivilegedAction<Void>)() -> {
-                    executor.execute(r1); // all throwables must be caught
-                    return null;
-                }, acc);
-        } else {
-            executor.execute(r1); // all throwables must be caught
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/FilterFactory.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.LinkedList;
-import java.util.List;
-
-class FilterFactory {
-
-    final LinkedList<Class<? extends HeaderFilter>> filterClasses = new LinkedList<>();
-
-    public void addFilter(Class<? extends HeaderFilter> type) {
-        filterClasses.add(type);
-    }
-
-    List<HeaderFilter> getFilterChain() {
-        List<HeaderFilter> l = new LinkedList<>();
-        for (Class<? extends HeaderFilter> clazz : filterClasses) {
-            try {
-                @SuppressWarnings("deprecation")
-                HeaderFilter headerFilter = clazz.newInstance();
-                l.add(headerFilter);
-            } catch (ReflectiveOperationException e) {
-                throw new InternalError(e);
-            }
-        }
-        return l;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/FrameReader.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Represents one frame. May be initialized with a leftover buffer from previous
- * frame. Call {@code haveFrame()} to determine if buffers contains at least one
- * frame. If false, the obtain another buffer and call {@code}input(ByteBuffer)}.
- * There may be additional bytes at end of the frame list.
- */
-class FrameReader {
-
-    final List<ByteBuffer> buffers;
-
-    FrameReader() {
-        buffers = new LinkedList<>();
-    }
-
-    FrameReader(FrameReader that) {
-        this.buffers = that.buffers;
-    }
-
-    FrameReader(ByteBuffer remainder) {
-        buffers = new LinkedList<>();
-        if (remainder != null) {
-            buffers.add(remainder);
-        }
-    }
-
-    public synchronized void input(ByteBuffer buffer) {
-        buffers.add(buffer);
-    }
-
-    public synchronized boolean haveFrame() {
-        //buffers = Utils.superCompact(buffers, () -> ByteBuffer.allocate(Utils.BUFSIZE));
-        int size = 0;
-        for (ByteBuffer buffer : buffers) {
-            size += buffer.remaining();
-        }
-        if (size < 3) {
-            return false; // don't have length yet
-        }
-        // we at least have length field
-        int length = 0;
-        int j = 0;
-        ByteBuffer b = buffers.get(j);
-        b.mark();
-        for (int i=0; i<3; i++) {
-            while (!b.hasRemaining()) {
-                b.reset();
-                b = buffers.get(++j);
-                b.mark();
-            }
-            length = (length << 8) + (b.get() & 0xff);
-        }
-        b.reset();
-        return (size >= length + 9); // frame length
-    }
-
-    synchronized List<ByteBuffer> frame() {
-        return buffers;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/GoAwayFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class GoAwayFrame extends ErrorFrame {
-
-    GoAwayFrame() {
-        type = TYPE;
-    }
-
-    int lastStream;
-    byte[] debugData = new byte[0];
-
-    public static final int TYPE = 0x7;
-
-    // Flags
-    public static final int ACK = 0x1;
-
-    public void setDebugData(byte[] debugData) {
-        this.debugData = debugData;
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + " Debugdata: " + new String(debugData);
-    }
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-        case ACK:
-            return "ACK";
-        }
-        return super.flagAsString(flag);
-    }
-
-    public void setLastStream(int lastStream) {
-        this.lastStream = lastStream;
-    }
-
-    public int getLastStream() {
-        return this.lastStream;
-    }
-
-    public byte[] getDebugData() {
-        return debugData;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if (length < 8) {
-            throw new IOException("Invalid GoAway frame");
-        }
-        lastStream = bc.getInt() & 0x7fffffff;
-        errorCode = bc.getInt();
-        //debugData = bc.getBytes(8);
-        int datalen = length - 8;
-        if (datalen > 0) {
-            debugData = bc.getBytes(datalen);
-            Log.logError("GoAway debugData " + new String(debugData));
-        }
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(length);
-        buf.putInt(lastStream);
-        buf.putInt(errorCode);
-        if (length > 8) {
-            buf.put(debugData);
-        }
-    }
-
-    @Override
-    void computeLength() {
-        length = 8 + debugData.length;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HeaderFilter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-/**
- * A header filter that can examine or modify, typically system headers for
- * requests before they are sent, and responses before they are returned to the
- * user. Some ability to resend requests is provided.
- *
- */
-interface HeaderFilter {
-
-    void request(HttpRequestImpl r) throws IOException;
-
-    /**
-     * Returns null if response ok to be given to user.  Non null is a request
-     * that must be resent and its response given to user. If impl throws an
-     * exception that is returned to user instead.
-     */
-    HttpRequestImpl response(HttpResponseImpl r) throws IOException;
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HeaderFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-/**
- * Either a HeadersFrame or a ContinuationFrame
- */
-abstract class HeaderFrame extends Http2Frame {
-
-    int offset;
-    int number;
-    int headerLength;
-    ByteBuffer[] headerBlocks;
-
-    public static final int END_HEADERS = 0x4;
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-        case END_HEADERS:
-            return "END_HEADERS";
-        }
-        return super.flagAsString(flag);
-    }
-
-    /**
-     * Sets the array of hpack encoded ByteBuffers
-     */
-    public void setHeaderBlock(ByteBuffer bufs[], int offset, int number) {
-        this.headerBlocks = bufs;
-        this.offset = offset;
-        this.number = number;
-        int length = 0;
-        for (int i=offset; i<offset+number; i++) {
-            length += headerBlocks[i].remaining();
-        }
-        this.headerLength = length;
-    }
-
-    public void setHeaderBlock(ByteBuffer bufs[]) {
-        setHeaderBlock(bufs, 0, bufs.length);
-    }
-
-    public ByteBuffer[] getHeaderBlock() {
-        return headerBlocks;
-    }
-
-    /**
-     * Returns true if this block is the final block of headers
-     */
-    public abstract boolean endHeaders();
-
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HeaderParser.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.Iterator;
-import java.util.Locale;
-import java.util.NoSuchElementException;
-
-/* This is useful for the nightmare of parsing multi-part HTTP/RFC822 headers
- * sensibly:
- * From a String like: 'timeout=15, max=5'
- * create an array of Strings:
- * { {"timeout", "15"},
- *   {"max", "5"}
- * }
- * From one like: 'Basic Realm="FuzzFace" Foo="Biz Bar Baz"'
- * create one like (no quotes in literal):
- * { {"basic", null},
- *   {"realm", "FuzzFace"}
- *   {"foo", "Biz Bar Baz"}
- * }
- * keys are converted to lower case, vals are left as is....
- */
-class HeaderParser {
-
-    /* table of key/val pairs */
-    String raw;
-    String[][] tab;
-    int nkeys;
-    int asize = 10; // initial size of array is 10
-
-    public HeaderParser(String raw) {
-        this.raw = raw;
-        tab = new String[asize][2];
-        parse();
-    }
-
-    private HeaderParser () { }
-
-    /**
-     * Creates a new HeaderParser from this, whose keys (and corresponding
-     * values) range from "start" to "end-1"
-     */
-    public HeaderParser subsequence(int start, int end) {
-        if (start == 0 && end == nkeys) {
-            return this;
-        }
-        if (start < 0 || start >= end || end > nkeys)
-            throw new IllegalArgumentException("invalid start or end");
-        HeaderParser n = new HeaderParser();
-        n.tab = new String [asize][2];
-        n.asize = asize;
-        System.arraycopy (tab, start, n.tab, 0, (end-start));
-        n.nkeys= (end-start);
-        return n;
-    }
-
-    private void parse() {
-
-        if (raw != null) {
-            raw = raw.trim();
-            char[] ca = raw.toCharArray();
-            int beg = 0, end = 0, i = 0;
-            boolean inKey = true;
-            boolean inQuote = false;
-            int len = ca.length;
-            while (end < len) {
-                char c = ca[end];
-                if ((c == '=') && !inQuote) { // end of a key
-                    tab[i][0] = new String(ca, beg, end-beg).toLowerCase(Locale.US);
-                    inKey = false;
-                    end++;
-                    beg = end;
-                } else if (c == '\"') {
-                    if (inQuote) {
-                        tab[i++][1]= new String(ca, beg, end-beg);
-                        inQuote=false;
-                        do {
-                            end++;
-                        } while (end < len && (ca[end] == ' ' || ca[end] == ','));
-                        inKey=true;
-                        beg=end;
-                    } else {
-                        inQuote=true;
-                        end++;
-                        beg=end;
-                    }
-                } else if (c == ' ' || c == ',') { // end key/val, of whatever we're in
-                    if (inQuote) {
-                        end++;
-                        continue;
-                    } else if (inKey) {
-                        tab[i++][0] = (new String(ca, beg, end-beg)).toLowerCase(Locale.US);
-                    } else {
-                        tab[i++][1] = (new String(ca, beg, end-beg));
-                    }
-                    while (end < len && (ca[end] == ' ' || ca[end] == ',')) {
-                        end++;
-                    }
-                    inKey = true;
-                    beg = end;
-                } else {
-                    end++;
-                }
-                if (i == asize) {
-                    asize = asize * 2;
-                    String[][] ntab = new String[asize][2];
-                    System.arraycopy (tab, 0, ntab, 0, tab.length);
-                    tab = ntab;
-                }
-            }
-            // get last key/val, if any
-            if (--end > beg) {
-                if (!inKey) {
-                    if (ca[end] == '\"') {
-                        tab[i++][1] = (new String(ca, beg, end-beg));
-                    } else {
-                        tab[i++][1] = (new String(ca, beg, end-beg+1));
-                    }
-                } else {
-                    tab[i++][0] = (new String(ca, beg, end-beg+1)).toLowerCase();
-                }
-            } else if (end == beg) {
-                if (!inKey) {
-                    if (ca[end] == '\"') {
-                        tab[i++][1] = String.valueOf(ca[end-1]);
-                    } else {
-                        tab[i++][1] = String.valueOf(ca[end]);
-                    }
-                } else {
-                    tab[i++][0] = String.valueOf(ca[end]).toLowerCase();
-                }
-            }
-            nkeys=i;
-        }
-    }
-
-    public String findKey(int i) {
-        if (i < 0 || i > asize)
-            return null;
-        return tab[i][0];
-    }
-
-    public String findValue(int i) {
-        if (i < 0 || i > asize)
-            return null;
-        return tab[i][1];
-    }
-
-    public String findValue(String key) {
-        return findValue(key, null);
-    }
-
-    public String findValue(String k, String Default) {
-        if (k == null)
-            return Default;
-        k = k.toLowerCase(Locale.US);
-        for (int i = 0; i < asize; ++i) {
-            if (tab[i][0] == null) {
-                return Default;
-            } else if (k.equals(tab[i][0])) {
-                return tab[i][1];
-            }
-        }
-        return Default;
-    }
-
-    class ParserIterator implements Iterator<String> {
-        int index;
-        boolean returnsValue; // or key
-
-        ParserIterator (boolean returnValue) {
-            returnsValue = returnValue;
-        }
-        @Override
-        public boolean hasNext () {
-            return index<nkeys;
-        }
-        @Override
-        public String next () {
-            if (index >= nkeys)
-                throw new NoSuchElementException();
-            return tab[index++][returnsValue?1:0];
-        }
-    }
-
-    public Iterator<String> keys () {
-        return new ParserIterator (false);
-    }
-
-    public Iterator<String> values () {
-        return new ParserIterator (true);
-    }
-
-    @Override
-    public String toString () {
-        Iterator<String> k = keys();
-        StringBuilder sb = new StringBuilder();
-        sb.append("{size=").append(asize).append(" nkeys=").append(nkeys)
-                .append(' ');
-        for (int i=0; k.hasNext(); i++) {
-            String key = k.next();
-            String val = findValue (i);
-            if (val != null && "".equals (val)) {
-                val = null;
-            }
-            sb.append(" {").append(key).append(val == null ? "" : "," + val)
-                    .append('}');
-            if (k.hasNext()) {
-                sb.append (',');
-            }
-        }
-        sb.append (" }");
-        return sb.toString();
-    }
-
-    public int findInt(String k, int Default) {
-        try {
-            return Integer.parseInt(findValue(k, String.valueOf(Default)));
-        } catch (Throwable t) {
-            return Default;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HeadersFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class HeadersFrame extends HeaderFrame {
-
-    public final static int TYPE = 0x1;
-
-    // Flags
-    public static final int END_STREAM = 0x1;
-    public static final int PADDED = 0x8;
-    public static final int PRIORITY = 0x20;
-
-
-    int padLength;
-    int streamDependency;
-    int weight;
-    boolean exclusive;
-
-    HeadersFrame() {
-        type = TYPE;
-    }
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-            case END_STREAM:
-                return "END_STREAM";
-            case PADDED:
-                return "PADDED";
-            case PRIORITY:
-                return "PRIORITY";
-        }
-        return super.flagAsString(flag);
-    }
-
-    public void setPadLength(int padLength) {
-        this.padLength = padLength;
-        flags |= PADDED;
-    }
-
-    public void setPriority(int streamDependency, boolean exclusive, int weight) {
-        this.streamDependency = streamDependency;
-        this.exclusive = exclusive;
-        this.weight = weight;
-        this.flags |= PRIORITY;
-    }
-
-    public int getStreamDependency() {
-        return streamDependency;
-    }
-
-    public int getWeight() {
-        return weight;
-    }
-
-    @Override
-    public boolean endHeaders() {
-        return getFlag(END_HEADERS);
-    }
-
-    public boolean getExclusive() {
-        return exclusive;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if ((flags & PADDED) != 0) {
-            padLength = bc.getByte();
-        }
-        if ((flags & PRIORITY) != 0) {
-            int x = bc.getInt();
-            exclusive = (x & 0x80000000) != 0;
-            streamDependency = x & 0x7fffffff;
-            weight = bc.getByte();
-        }
-        headerLength = length - padLength;
-        headerBlocks = bc.getBuffers(headerLength);
-    }
-
-    @Override
-    void computeLength() {
-        int len = 0;
-        if ((flags & PADDED) != 0) {
-            len += (1 + padLength);
-        }
-        if ((flags & PRIORITY) != 0) {
-            len += 5;
-        }
-        len += headerLength;
-        this.length = len;
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(6);
-        if ((flags & PADDED) != 0) {
-            buf.put((byte)padLength);
-        }
-        if ((flags & PRIORITY) != 0) {
-            int x = exclusive ? 1 << 31 + streamDependency : streamDependency;
-            buf.putInt(x);
-            buf.put((byte)weight);
-        }
-        for (int i=0; i<headerBlocks.length; i++) {
-            bg.addByteBuffer(headerBlocks[i]);
-        }
-        if ((flags & PADDED) != 0) {
-            bg.addPadding(padLength);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http1Exchange.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.net.URI;
-import java.util.concurrent.CompletableFuture;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Encapsulates one HTTP/1.1 request/responseAsync exchange.
- */
-class Http1Exchange extends ExchangeImpl {
-
-    final HttpRequestImpl request;        // main request
-    final List<CompletableFuture<?>> operations; // used for cancel
-    final Http1Request requestAction;
-    volatile Http1Response response;
-    final HttpConnection connection;
-    final HttpClientImpl client;
-    final ExecutorWrapper executor;
-
-    @Override
-    public String toString() {
-        return request.toString();
-    }
-
-    HttpRequestImpl request() {
-        return request;
-    }
-
-    Http1Exchange(Exchange exchange, HttpConnection connection)
-        throws IOException
-    {
-        super(exchange);
-        this.request = exchange.request();
-        this.client = request.client();
-        this.executor = client.executorWrapper();
-        this.operations = Collections.synchronizedList(new LinkedList<>());
-        if (connection != null) {
-            this.connection = connection;
-        } else {
-            InetSocketAddress addr = Utils.getAddress(request);
-            this.connection = HttpConnection.getConnection(addr, request);
-        }
-        this.requestAction = new Http1Request(request, this.connection);
-    }
-
-
-    HttpConnection connection() {
-        return connection;
-    }
-
-    @Override
-    <T> T responseBody(HttpResponse.BodyProcessor<T> processor)
-        throws IOException
-    {
-        return responseBody(processor, true);
-    }
-
-    <T> T responseBody(HttpResponse.BodyProcessor<T> processor,
-                       boolean return2Cache)
-        throws IOException
-    {
-        try {
-            T body = response.readBody(processor, return2Cache);
-            return body;
-        } catch (Throwable t) {
-            connection.close();
-            throw t;
-        }
-    }
-
-    @Override
-    <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
-        CompletableFuture<T> cf = new CompletableFuture<>();
-        request.client()
-               .executorWrapper()
-               .execute(() -> {
-                            try {
-                                T body = responseBody(processor);
-                                cf.complete(body);
-                            } catch (Throwable e) {
-                                cf.completeExceptionally(e);
-                            }
-                        },
-                        () -> response.response.getAccessControlContext()); // TODO: fix
-        return cf;
-    }
-
-    @Override
-    void sendHeadersOnly() throws IOException, InterruptedException {
-        try {
-            if (!connection.connected()) {
-                connection.connect();
-            }
-            requestAction.sendHeadersOnly();
-        } catch (Throwable e) {
-            connection.close();
-            throw e;
-        }
-    }
-
-    @Override
-    void sendBody() throws IOException {
-        try {
-            requestAction.continueRequest();
-        } catch (Throwable e) {
-            connection.close();
-            throw e;
-        }
-    }
-
-    @Override
-    HttpResponseImpl getResponse() throws IOException {
-        try {
-            response = new Http1Response(connection, this);
-            response.readHeaders();
-            return response.response();
-        } catch (Throwable t) {
-            connection.close();
-            throw t;
-        }
-    }
-
-    @Override
-    void sendRequest() throws IOException, InterruptedException {
-        try {
-            if (!connection.connected()) {
-                connection.connect();
-            }
-            requestAction.sendRequest();
-        } catch (Throwable t) {
-            connection.close();
-            throw t;
-        }
-    }
-
-    private void closeConnection() {
-        connection.close();
-    }
-
-    @Override
-    CompletableFuture<Void> sendHeadersAsync() {
-        if (!connection.connected()) {
-            CompletableFuture<Void> op = connection.connectAsync()
-                    .thenCompose(this::sendHdrsAsyncImpl)
-                    .whenComplete((Void b, Throwable t) -> {
-                        if (t != null)
-                            closeConnection();
-                    });
-            operations.add(op);
-            return op;
-        } else {
-            return sendHdrsAsyncImpl(null);
-        }
-    }
-
-    private CompletableFuture<Void> sendHdrsAsyncImpl(Void v) {
-        CompletableFuture<Void> cf = new CompletableFuture<>();
-        executor.execute(() -> {
-                            try {
-                                requestAction.sendHeadersOnly();
-                                cf.complete(null);
-                            } catch (Throwable e) {
-                                cf.completeExceptionally(e);
-                                connection.close();
-                            }
-                         },
-                request::getAccessControlContext);
-        operations.add(cf);
-        return cf;
-    }
-
-    /**
-     * Cancel checks to see if request and responseAsync finished already.
-     * If not it closes the connection and completes all pending operations
-     */
-    @Override
-    synchronized void cancel() {
-        if (requestAction != null && requestAction.finished()
-                && response != null && response.finished()) {
-            return;
-        }
-        connection.close();
-        IOException e = new IOException("Request cancelled");
-        int count = 0;
-        for (CompletableFuture<?> cf : operations) {
-            cf.completeExceptionally(e);
-            count++;
-        }
-        Log.logError("Http1Exchange.cancel: count=" + count);
-    }
-
-    CompletableFuture<HttpResponseImpl> getResponseAsyncImpl(Void v) {
-        CompletableFuture<HttpResponseImpl> cf = new CompletableFuture<>();
-        try {
-            response = new Http1Response(connection, Http1Exchange.this);
-            response.readHeaders();
-            cf.complete(response.response());
-        } catch (IOException e) {
-            cf.completeExceptionally(e);
-        }
-        return cf;
-    }
-
-    @Override
-    CompletableFuture<HttpResponseImpl> getResponseAsync(Void v) {
-        CompletableFuture<HttpResponseImpl> cf =
-            connection.whenReceivingResponse()
-                      .thenCompose(this::getResponseAsyncImpl);
-
-        operations.add(cf);
-        return cf;
-    }
-
-    @Override
-    CompletableFuture<Void> sendBodyAsync() {
-        final CompletableFuture<Void> cf = new CompletableFuture<>();
-        executor.execute(() -> {
-            try {
-                requestAction.continueRequest();
-                cf.complete(null);
-            } catch (Throwable e) {
-                cf.completeExceptionally(e);
-                connection.close();
-            }
-        }, request::getAccessControlContext);
-        operations.add(cf);
-        return cf;
-    }
-
-    @Override
-    CompletableFuture<Void> sendRequestAsync() {
-        CompletableFuture<Void> op;
-        if (!connection.connected()) {
-            op = connection.connectAsync()
-                .thenCompose(this::sendRequestAsyncImpl)
-                .whenComplete((Void v, Throwable t) -> {
-                    if (t != null) {
-                        closeConnection();
-                    }
-                });
-        } else {
-            op = sendRequestAsyncImpl(null);
-        }
-        operations.add(op);
-        return op;
-    }
-
-    CompletableFuture<Void> sendRequestAsyncImpl(Void v) {
-        CompletableFuture<Void> cf = new CompletableFuture<>();
-        executor.execute(() -> {
-            try {
-                requestAction.sendRequest();
-                cf.complete(null);
-            } catch (Throwable e) {
-                cf.completeExceptionally(e);
-                connection.close();
-            }
-        }, request::getAccessControlContext);
-        operations.add(cf);
-        return cf;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http1Request.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.URI;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.net.InetSocketAddress;
-import java.net.http.HttpConnection.Mode;
-import java.nio.charset.StandardCharsets;
-import java.util.function.LongConsumer;
-import static java.nio.charset.StandardCharsets.US_ASCII;
-
-/**
- *  A HTTP/1.1 request.
- *
- * send() -> Writes the request + body to the given channel, in one blocking
- * operation.
- */
-class Http1Request {
-
-    final HttpRequestImpl request;
-    final HttpConnection chan;
-    // Multiple buffers are used to hold different parts of request
-    // See line 206 and below for description
-    final ByteBuffer[] buffers;
-    final HttpRequest.BodyProcessor requestProc;
-    final HttpHeaders userHeaders;
-    final HttpHeadersImpl systemHeaders;
-    final LongConsumer flowController;
-    boolean streaming;
-    long contentLength;
-
-    Http1Request(HttpRequestImpl request, HttpConnection connection)
-        throws IOException
-    {
-        this.request = request;
-        this.chan = connection;
-        buffers = new ByteBuffer[5]; // TODO: check
-        this.requestProc = request.requestProcessor();
-        this.userHeaders = request.getUserHeaders();
-        this.systemHeaders = request.getSystemHeaders();
-        this.flowController = this::dummy;
-    }
-
-    private void logHeaders() throws IOException {
-        StringBuilder sb = new StringBuilder(256);
-        sb.append("REQUEST HEADERS:\r\n");
-        collectHeaders1(sb, request, systemHeaders);
-        collectHeaders1(sb, request, userHeaders);
-        Log.logHeaders(sb.toString());
-    }
-
-    private void dummy(long x) {
-        // not used in this class
-    }
-
-    private void collectHeaders0() throws IOException {
-        if (Log.headers()) {
-            logHeaders();
-        }
-        StringBuilder sb = new StringBuilder(256);
-        collectHeaders1(sb, request, systemHeaders);
-        collectHeaders1(sb, request, userHeaders);
-        sb.append("\r\n");
-        String headers = sb.toString();
-        buffers[1] = ByteBuffer.wrap(headers.getBytes(StandardCharsets.US_ASCII));
-    }
-
-    private void collectHeaders1(StringBuilder sb,
-                                 HttpRequestImpl request,
-                                 HttpHeaders headers)
-        throws IOException
-    {
-        Map<String,List<String>> h = headers.map();
-        Set<Map.Entry<String,List<String>>> entries = h.entrySet();
-
-        for (Map.Entry<String,List<String>> entry : entries) {
-            String key = entry.getKey();
-            List<String> values = entry.getValue();
-            for (String value : values) {
-                sb.append(key)
-                  .append(": ")
-                  .append(value)
-                  .append("\r\n");
-            }
-        }
-    }
-
-    private String getPathAndQuery(URI uri) {
-        String path = uri.getPath();
-        String query = uri.getQuery();
-        if (path == null || path.equals("")) {
-            path = "/";
-        }
-        if (query == null) {
-            query = "";
-        }
-        if (query.equals("")) {
-            return path;
-        } else {
-            return path + "?" + query;
-        }
-    }
-
-    private String authorityString(InetSocketAddress addr) {
-        return addr.getHostString() + ":" + addr.getPort();
-    }
-
-    private String hostString() {
-        URI uri = request.uri();
-        int port = uri.getPort();
-        String host = uri.getHost();
-
-        boolean defaultPort;
-        if (port == -1)
-            defaultPort = true;
-        else if (request.secure())
-            defaultPort = port == 443;
-        else
-            defaultPort = port == 80;
-
-        if (defaultPort)
-            return host;
-        else
-            return host + ":" + Integer.toString(port);
-    }
-
-    private String requestURI() {
-        URI uri = request.uri();
-        String method = request.method();
-
-        if ((request.proxy() == null && !method.equals("CONNECT"))
-                || request.isWebSocket()) {
-            return getPathAndQuery(uri);
-        }
-        if (request.secure()) {
-            if (request.method().equals("CONNECT")) {
-                // use authority for connect itself
-                return authorityString(request.authority());
-            } else {
-                // requests over tunnel do not require full URL
-                return getPathAndQuery(uri);
-            }
-        }
-        return uri == null? authorityString(request.authority()) : uri.toString();
-    }
-
-    void sendHeadersOnly() throws IOException {
-        collectHeaders();
-        chan.write(buffers, 0, 2);
-    }
-
-    void sendRequest() throws IOException {
-        collectHeaders();
-        chan.configureMode(Mode.BLOCKING);
-        if (contentLength == 0) {
-            chan.write(buffers, 0, 2);
-        } else if (contentLength > 0) {
-            writeFixedContent(true);
-        } else {
-            writeStreamedContent(true);
-        }
-        setFinished();
-    }
-
-    private boolean finished;
-
-    synchronized boolean finished() {
-        return  finished;
-    }
-
-    synchronized void setFinished() {
-        finished = true;
-    }
-
-    private void collectHeaders() throws IOException {
-        if (Log.requests() && request != null) {
-            Log.logRequest(request.toString());
-        }
-        String uriString = requestURI();
-        StringBuilder sb = new StringBuilder(64);
-        sb.append(request.method())
-          .append(' ')
-          .append(uriString)
-          .append(" HTTP/1.1\r\n");
-        String cmd = sb.toString();
-
-        buffers[0] = ByteBuffer.wrap(cmd.getBytes(StandardCharsets.US_ASCII));
-        URI uri = request.uri();
-        if (uri != null) {
-            systemHeaders.setHeader("Host", hostString());
-        }
-        if (request == null) {
-            // this is not a user request. No content
-            contentLength = 0;
-        } else {
-            contentLength = requestProc.onRequestStart(request, flowController);
-        }
-
-        if (contentLength == 0) {
-            systemHeaders.setHeader("Content-Length", "0");
-            collectHeaders0();
-        } else if (contentLength > 0) {
-            /* [0] request line [1] headers [2] body  */
-            systemHeaders.setHeader("Content-Length",
-                                    Integer.toString((int) contentLength));
-            streaming = false;
-            collectHeaders0();
-            buffers[2] = chan.getBuffer();
-        } else {
-            /* Chunked:
-             *
-             * [0] request line [1] headers [2] chunk header [3] chunk data [4]
-             * final chunk header and trailing CRLF of previous chunks
-             *
-             * 2,3,4 used repeatedly */
-            streaming = true;
-            systemHeaders.setHeader("Transfer-encoding", "chunked");
-            collectHeaders0();
-            buffers[3] = chan.getBuffer();
-        }
-    }
-
-    // The following two methods used by Http1Exchange to handle expect continue
-
-    void continueRequest() throws IOException {
-        if (streaming) {
-            writeStreamedContent(false);
-        } else {
-            writeFixedContent(false);
-        }
-        setFinished();
-    }
-
-    /* Entire request is sent, or just body only  */
-    private void writeStreamedContent(boolean includeHeaders)
-        throws IOException
-    {
-        if (requestProc instanceof HttpRequest.BodyProcessor) {
-            HttpRequest.BodyProcessor pullproc = requestProc;
-            int startbuf, nbufs;
-
-            if (includeHeaders) {
-                startbuf = 0;
-                nbufs = 5;
-            } else {
-                startbuf = 2;
-                nbufs = 3;
-            }
-            try {
-                // TODO: currently each write goes out as one chunk
-                // TODO: should be collecting data and buffer it.
-
-                buffers[3].clear();
-                boolean done = pullproc.onRequestBodyChunk(buffers[3]);
-                int chunklen = buffers[3].position();
-                buffers[2] = getHeader(chunklen);
-                buffers[3].flip();
-                buffers[4] = CRLF_BUFFER();
-                chan.write(buffers, startbuf, nbufs);
-                while (!done) {
-                    buffers[3].clear();
-                    done = pullproc.onRequestBodyChunk(buffers[3]);
-                    if (done)
-                        break;
-                    buffers[3].flip();
-                    chunklen = buffers[3].remaining();
-                    buffers[2] = getHeader(chunklen);
-                    buffers[4] = CRLF_BUFFER();
-                    chan.write(buffers, 2, 3);
-                }
-                buffers[3] = EMPTY_CHUNK_HEADER();
-                buffers[4] = CRLF_BUFFER();
-                chan.write(buffers, 3, 2);
-            } catch (IOException e) {
-                requestProc.onRequestError(e);
-                throw e;
-            }
-        }
-    }
-    /* Entire request is sent, or just body only */
-    private void writeFixedContent(boolean includeHeaders)
-        throws IOException
-    {
-        try {
-            int startbuf, nbufs;
-
-            if (contentLength == 0) {
-                return;
-            }
-            if (includeHeaders) {
-                startbuf = 0;
-                nbufs = 3;
-            } else {
-                startbuf = 2;
-                nbufs = 1;
-                buffers[0].clear().flip();
-                buffers[1].clear().flip();
-            }
-            buffers[2] = chan.getBuffer();
-            if (requestProc instanceof HttpRequest.BodyProcessor) {
-                HttpRequest.BodyProcessor pullproc = requestProc;
-
-                boolean done = pullproc.onRequestBodyChunk(buffers[2]);
-                buffers[2].flip();
-                long headersLength = buffers[0].remaining() + buffers[1].remaining();
-                long contentWritten = buffers[2].remaining();
-                chan.checkWrite(headersLength + contentWritten,
-                                buffers,
-                                startbuf,
-                                nbufs);
-                while (!done) {
-                    buffers[2].clear();
-                    done = pullproc.onRequestBodyChunk(buffers[2]);
-                    buffers[2].flip();
-                    long len = buffers[2].remaining();
-                    if (contentWritten + len > contentLength) {
-                        break;
-                    }
-                    chan.checkWrite(len, buffers[2]);
-                    contentWritten += len;
-                }
-                if (contentWritten != contentLength) {
-                    throw new IOException("wrong content length");
-                }
-            }
-        } catch (IOException e) {
-            requestProc.onRequestError(e);
-            throw e;
-        }
-    }
-
-    private static final byte[] CRLF = {'\r', '\n'};
-    private static final byte[] EMPTY_CHUNK_BYTES = {'0', '\r', '\n'};
-
-    private ByteBuffer CRLF_BUFFER() {
-        return ByteBuffer.wrap(CRLF);
-    }
-
-    private ByteBuffer EMPTY_CHUNK_HEADER() {
-        return ByteBuffer.wrap(EMPTY_CHUNK_BYTES);
-    }
-
-    /* Returns a header for a particular chunk size */
-    private static ByteBuffer getHeader(int size){
-        String hexStr =  Integer.toHexString(size);
-        byte[] hexBytes = hexStr.getBytes(US_ASCII);
-        byte[] header = new byte[hexStr.length()+2];
-        System.arraycopy(hexBytes, 0, header, 0, hexBytes.length);
-        header[hexBytes.length] = CRLF[0];
-        header[hexBytes.length+1] = CRLF[1];
-        return ByteBuffer.wrap(header);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http1Response.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.LongConsumer;
-import static java.net.http.HttpClient.Version.HTTP_1_1;
-
-/**
- * Handles a HTTP/1.1 response in two blocking calls. readHeaders() and
- * readBody(). There can be more than one of these per Http exchange.
- */
-class Http1Response {
-
-    private ResponseContent content;
-    private final HttpRequestImpl request;
-    HttpResponseImpl response;
-    private final HttpConnection connection;
-    private ResponseHeaders headers;
-    private int responseCode;
-    private ByteBuffer buffer; // same buffer used for reading status line and headers
-    private final Http1Exchange exchange;
-    private final boolean redirecting; // redirecting
-    private boolean return2Cache; // return connection to cache when finished
-
-    Http1Response(HttpConnection conn, Http1Exchange exchange) {
-        this.request = exchange.request();
-        this.exchange = exchange;
-        this.connection = conn;
-        this.redirecting = false;
-        buffer = connection.getRemaining();
-    }
-
-    // called when the initial read should come from a buffer left
-    // over from a previous response.
-    void setBuffer(ByteBuffer buffer) {
-        this.buffer = buffer;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void readHeaders() throws IOException {
-        String statusline = readStatusLine();
-        if (statusline == null) {
-            if (Log.errors()) {
-                Log.logError("Connection closed. Retry");
-            }
-            connection.close();
-            // connection was closed
-            throw new IOException("Connection closed");
-        }
-        if (!statusline.startsWith("HTTP/1.")) {
-            throw new IOException("Invalid status line: " + statusline);
-        }
-        char c = statusline.charAt(7);
-        responseCode = Integer.parseInt(statusline.substring(9, 12));
-
-        headers = new ResponseHeaders(connection, buffer);
-        headers.initHeaders();
-        if (Log.headers()) {
-            logHeaders(headers);
-        }
-        response = new HttpResponseImpl(responseCode,
-                                        exchange.exchange,
-                                        headers,
-                                        null,
-                                        connection.sslParameters(),
-                                        HTTP_1_1,
-                                        connection);
-    }
-
-    private boolean finished;
-
-    synchronized void completed() {
-        finished = true;
-    }
-
-    synchronized boolean finished() {
-        return finished;
-    }
-
-    // Blocking flow controller implementation. Only works when a
-    // thread is dedicated to reading response body
-
-    static class FlowController implements LongConsumer {
-        long window ;
-
-        @Override
-        public synchronized void accept(long value) {
-            window += value;
-            notifyAll();
-        }
-
-        public synchronized void request(long value) throws InterruptedException {
-            while (window < value) {
-                wait();
-            }
-            window -= value;
-        }
-    }
-
-    FlowController flowController;
-
-    int fixupContentLen(int clen) {
-        if (request.method().equalsIgnoreCase("HEAD")) {
-            return 0;
-        }
-        if (clen == -1) {
-            if (headers.firstValue("Transfer-encoding").orElse("")
-                       .equalsIgnoreCase("chunked")) {
-                return -1;
-            }
-            return 0;
-        }
-        return clen;
-    }
-
-    private void returnBuffer(ByteBuffer buf) {
-        // not currently used, but will be when we change SSL to use fixed
-        // sized buffers and a single buffer pool for HttpClientImpl
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T readBody(java.net.http.HttpResponse.BodyProcessor<T> p,
-                          boolean return2Cache)
-        throws IOException
-    {
-        T body = null; // TODO: check null case below
-        this.return2Cache = return2Cache;
-        final java.net.http.HttpResponse.BodyProcessor<T> pusher = p;
-
-        int clen0 = headers.getContentLength();
-        final int clen = fixupContentLen(clen0);
-
-        flowController = new FlowController();
-
-        body = pusher.onResponseBodyStart(clen, headers, flowController);
-
-        ExecutorWrapper executor;
-        if (body == null) {
-            executor = ExecutorWrapper.callingThread();
-        } else {
-            executor = request.client().executorWrapper();
-        }
-
-        final ResponseHeaders h = headers;
-        if (body == null) {
-            content = new ResponseContent(connection,
-                                          clen,
-                                          h,
-                                          pusher,
-                                          flowController);
-            content.pushBody(headers.getResidue());
-            body = pusher.onResponseComplete();
-            completed();
-            onFinished();
-            return body;
-        } else {
-            executor.execute(() -> {
-                    try {
-                        content = new ResponseContent(connection,
-                                                      clen,
-                                                      h,
-                                                      pusher,
-                                                      flowController);
-                        content.pushBody(headers.getResidue());
-                        pusher.onResponseComplete();
-                        completed();
-                        onFinished();
-                    } catch (Throwable e) {
-                        pusher.onResponseError(e);
-                    }
-                },
-                () -> response.getAccessControlContext());
-        }
-        return body;
-    }
-
-    private void onFinished() {
-        connection.buffer = content.getResidue();
-        if (return2Cache) {
-            connection.returnToCache(headers);
-        }
-    }
-
-    private void logHeaders(ResponseHeaders headers) {
-        Map<String, List<String>> h = headers.mapInternal();
-        Set<String> keys = h.keySet();
-        Set<Map.Entry<String, List<String>>> entries = h.entrySet();
-        for (Map.Entry<String, List<String>> entry : entries) {
-            String key = entry.getKey();
-            StringBuilder sb = new StringBuilder();
-            sb.append(key).append(": ");
-            List<String> values = entry.getValue();
-            if (values != null) {
-                for (String value : values) {
-                    sb.append(value).append(' ');
-                }
-            }
-            Log.logHeaders(sb.toString());
-        }
-    }
-
-    HttpResponseImpl response() {
-        return response;
-    }
-
-    boolean redirecting() {
-        return redirecting;
-    }
-
-    HttpHeaders responseHeaders() {
-        return headers;
-    }
-
-    int responseCode() {
-        return responseCode;
-    }
-
-    static final char CR = '\r';
-    static final char LF = '\n';
-
-    private ByteBuffer getBuffer() throws IOException {
-        if (buffer == null || !buffer.hasRemaining()) {
-            buffer = connection.read();
-        }
-        return buffer;
-    }
-
-    ByteBuffer buffer() {
-        return buffer;
-    }
-
-    String readStatusLine() throws IOException {
-        boolean cr = false;
-        StringBuilder statusLine = new StringBuilder(128);
-        ByteBuffer b;
-        while ((b = getBuffer()) != null) {
-            byte[] buf = b.array();
-            int offset = b.position();
-            int len = b.limit() - offset;
-
-            for (int i = 0; i < len; i++) {
-                char c = (char) buf[i+offset];
-
-                if (cr) {
-                    if (c == LF) {
-                        b.position(i + 1 + offset);
-                        return statusLine.toString();
-                    } else {
-                        throw new IOException("invalid status line");
-                    }
-                }
-                if (c == CR) {
-                    cr = true;
-                } else {
-                    statusLine.append(c);
-                }
-            }
-            // unlikely, but possible, that multiple reads required
-            b.position(b.limit());
-        }
-        return null;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http2ClientImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.net.URI;
-import static java.net.http.SettingsFrame.INITIAL_WINDOW_SIZE;
-import static java.net.http.SettingsFrame.ENABLE_PUSH;
-import static java.net.http.SettingsFrame.HEADER_TABLE_SIZE;
-import static java.net.http.SettingsFrame.MAX_CONCURRENT_STREAMS;
-import static java.net.http.SettingsFrame.MAX_FRAME_SIZE;
-import java.util.Base64;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- *  Http2 specific aspects of HttpClientImpl
- */
-class Http2ClientImpl {
-
-    final private HttpClientImpl client;
-
-    Http2ClientImpl(HttpClientImpl client) {
-        this.client = client;
-    }
-
-    /* Map key is "scheme:host:port" */
-    final private Map<String,Http2Connection> connections =
-            Collections.synchronizedMap(new HashMap<>());
-
-    final private Set<String> opening = Collections.synchronizedSet(new HashSet<>());
-
-    synchronized boolean haveConnectionFor(URI uri, InetSocketAddress proxy) {
-        return connections.containsKey(Http2Connection.keyFor(uri,proxy));
-    }
-
-    /**
-     * If a https request then blocks and waits until a connection is opened.
-     * Returns null if the request is 'http' as a different (upgrade)
-     * mechanism is used.
-     *
-     * Only one connection per destination is created. Blocks when opening
-     * connection, or when waiting for connection to be opened.
-     * First thread opens the connection and notifies the others when done.
-     *
-     * If the request is secure (https) then we open the connection here.
-     * If not, then the more complicated upgrade from 1.1 to 2 happens (not here)
-     * In latter case, when the Http2Connection is connected, putConnection() must
-     * be called to store it.
-     */
-    Http2Connection getConnectionFor(HttpRequestImpl req)
-            throws IOException, InterruptedException {
-        URI uri = req.uri();
-        InetSocketAddress proxy = req.proxy();
-        String key = Http2Connection.keyFor(uri, proxy);
-        Http2Connection connection;
-        synchronized (opening) {
-            while ((connection = connections.get(key)) == null) {
-                if (!req.secure()) {
-                    return null;
-                }
-                if (!opening.contains(key)) {
-                    opening.add(key);
-                    break;
-                } else {
-                    opening.wait();
-                }
-            }
-        }
-        if (connection != null) {
-            return connection;
-        }
-        // we are opening the connection here blocking until it is done.
-        connection = new Http2Connection(req);
-        synchronized (opening) {
-            connections.put(key, connection);
-            opening.remove(key);
-            opening.notifyAll();
-        }
-        return connection;
-    }
-
-
-    /*
-     * TODO: If there isn't a connection to the same destination, then
-     * store it. If there is already a connection, then close it
-     */
-    synchronized void putConnection(Http2Connection c) {
-        String key = c.key();
-        connections.put(key, c);
-    }
-
-    synchronized void deleteConnection(Http2Connection c) {
-        String key = c.key();
-        connections.remove(key);
-    }
-
-    HttpClientImpl client() {
-        return client;
-    }
-
-    /** Returns the client settings as a base64 (url) encoded string */
-    String getSettingsString() {
-        SettingsFrame sf = getClientSettings();
-        ByteBufferGenerator bg = new ByteBufferGenerator(client);
-        sf.writeOutgoing(bg);
-        byte[] settings = bg.asByteArray(9); // without the header
-        Base64.Encoder encoder = Base64.getUrlEncoder()
-                                       .withoutPadding();
-        return encoder.encodeToString(settings);
-    }
-
-    private static final int K = 1024;
-
-    SettingsFrame getClientSettings() {
-        SettingsFrame frame = new SettingsFrame();
-        frame.setParameter(HEADER_TABLE_SIZE, Utils.getIntegerNetProperty(
-            "java.net.httpclient.hpack.maxheadertablesize", 16 * K));
-        frame.setParameter(ENABLE_PUSH, Utils.getIntegerNetProperty(
-            "java.net.httpclient.enablepush", 1));
-        frame.setParameter(MAX_CONCURRENT_STREAMS, Utils.getIntegerNetProperty(
-            "java.net.httpclient.maxstreams", 16));
-        frame.setParameter(INITIAL_WINDOW_SIZE, Utils.getIntegerNetProperty(
-            "java.net.httpclient.windowsize", 32 * K));
-        frame.setParameter(MAX_FRAME_SIZE, Utils.getIntegerNetProperty(
-            "java.net.httpclient.maxframesize", 16 * K));
-        frame.computeLength();
-        return frame;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http2Connection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,791 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.net.URI;
-import java.net.http.HttpConnection.Mode;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import sun.net.httpclient.hpack.Encoder;
-import sun.net.httpclient.hpack.Decoder;
-import static java.net.http.SettingsFrame.*;
-import static java.net.http.Utils.BUFSIZE;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Formatter;
-import java.util.stream.Collectors;
-import sun.net.httpclient.hpack.DecodingCallback;
-
-/**
- * An Http2Connection. Encapsulates the socket(channel) and any SSLEngine used
- * over it. Contains an HttpConnection which hides the SocketChannel SSL stuff.
- *
- * Http2Connections belong to a Http2ClientImpl, (one of) which belongs
- * to a HttpClientImpl.
- *
- * Creation cases:
- * 1) upgraded HTTP/1.1 plain tcp connection
- * 2) prior knowledge directly created plain tcp connection
- * 3) directly created HTTP/2 SSL connection which uses ALPN.
- *
- * Sending is done by writing directly to underlying HttpConnection object which
- * is operating in async mode. No flow control applies on output at this level
- * and all writes are just executed as puts to an output Q belonging to HttpConnection
- * Flow control is implemented by HTTP/2 protocol itself.
- *
- * Hpack header compression
- * and outgoing stream creation is also done here, because these operations
- * must be synchronized at the socket level. Stream objects send frames simply
- * by placing them on the connection's output Queue. sendFrame() is called
- * from a higher level (Stream) thread.
- *
- * asyncReceive(ByteBuffer) is always called from the selector thread. It assembles
- * incoming Http2Frames, and directs them to the appropriate Stream.incoming()
- * or handles them directly itself. This thread performs hpack decompression
- * and incoming stream creation (Server push). Incoming frames destined for a
- * stream are provided by calling Stream.incoming().
- */
-class Http2Connection implements BufferHandler {
-
-    final Queue<Http2Frame> outputQ;
-    volatile boolean closed;
-
-    //-------------------------------------
-    final HttpConnection connection;
-    HttpClientImpl client;
-    final Http2ClientImpl client2;
-    Map<Integer,Stream> streams;
-    int nextstreamid = 3; // stream 1 is registered separately
-    int nextPushStream = 2;
-    Encoder hpackOut;
-    Decoder hpackIn;
-    SettingsFrame clientSettings, serverSettings;
-    ByteBufferConsumer bbc;
-    final LinkedList<ByteBuffer> freeList;
-    final String key; // for HttpClientImpl.connections map
-    FrameReader reader;
-
-    // Connection level flow control windows
-    int sendWindow = INITIAL_WINDOW_SIZE;
-
-    final static int DEFAULT_FRAME_SIZE = 16 * 1024;
-    private static ByteBuffer[] empty = Utils.EMPTY_BB_ARRAY;
-
-    final ExecutorWrapper executor;
-
-    /**
-     * This is established by the protocol spec and the peer will update it with
-     * WINDOW_UPDATEs, which affects the sendWindow.
-     */
-    final static int INITIAL_WINDOW_SIZE = 64 * 1024 - 1;
-
-    // TODO: need list of control frames from other threads
-    // that need to be sent
-
-    /**
-     * Case 1) Create from upgraded HTTP/1.1 connection.
-     * Is ready to use. Will not be SSL. exchange is the Exchange
-     * that initiated the connection, whose response will be delivered
-     * on a Stream.
-     */
-    Http2Connection(HttpConnection connection, Http2ClientImpl client2,
-            Exchange exchange) throws IOException, InterruptedException {
-        this.outputQ = new Queue<>();
-        String msg = "Connection send window size " + Integer.toString(sendWindow);
-        Log.logTrace(msg);
-
-        //this.initialExchange = exchange;
-        assert !(connection instanceof SSLConnection);
-        this.connection = connection;
-        this.client = client2.client();
-        this.client2 = client2;
-        this.executor = client.executorWrapper();
-        this.freeList = new LinkedList<>();
-        this.key = keyFor(connection);
-        streams = Collections.synchronizedMap(new HashMap<>());
-        initCommon();
-        //sendConnectionPreface();
-        Stream initialStream = createStream(exchange);
-        initialStream.registerStream(1);
-        initialStream.requestSent();
-        sendConnectionPreface();
-        connection.configureMode(Mode.ASYNC);
-        // start reading and writing
-        // start reading
-        AsyncConnection asyncConn = (AsyncConnection)connection;
-        asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown);
-        asyncReceive(connection.getRemaining());
-        asyncConn.startReading();
-    }
-
-    // async style but completes immediately
-    static CompletableFuture<Http2Connection> createAsync(HttpConnection connection,
-            Http2ClientImpl client2, Exchange exchange) {
-        CompletableFuture<Http2Connection> cf = new CompletableFuture<>();
-        try {
-            Http2Connection c = new Http2Connection(connection, client2, exchange);
-            cf.complete(c);
-        } catch (IOException | InterruptedException e) {
-            cf.completeExceptionally(e);
-        }
-        return cf;
-    }
-
-    /**
-     * Cases 2) 3)
-     *
-     * request is request to be sent.
-     */
-    Http2Connection(HttpRequestImpl request) throws IOException, InterruptedException {
-        InetSocketAddress proxy = request.proxy();
-        URI uri = request.uri();
-        InetSocketAddress addr = Utils.getAddress(request);
-        String msg = "Connection send window size " + Integer.toString(sendWindow);
-        Log.logTrace(msg);
-        this.key = keyFor(uri, proxy);
-        this.connection = HttpConnection.getConnection(addr, request, this);
-        streams = Collections.synchronizedMap(new HashMap<>());
-        this.client = request.client();
-        this.client2 = client.client2();
-        this.executor = client.executorWrapper();
-        this.freeList = new LinkedList<>();
-        this.outputQ = new Queue<>();
-        nextstreamid = 1;
-        initCommon();
-        connection.connect();
-        connection.configureMode(Mode.ASYNC);
-        // start reading
-        AsyncConnection asyncConn = (AsyncConnection)connection;
-        asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown);
-        sendConnectionPreface();
-        asyncConn.startReading();
-    }
-
-    // NEW
-    synchronized void obtainSendWindow(int amount) throws InterruptedException {
-        while (amount > 0) {
-            int n = Math.min(amount, sendWindow);
-            sendWindow -= n;
-            amount -= n;
-            if (amount > 0)
-                wait();
-        }
-    }
-
-    synchronized void updateSendWindow(int amount) {
-        if (sendWindow == 0) {
-            sendWindow += amount;
-            notifyAll();
-        } else
-            sendWindow += amount;
-    }
-
-    synchronized int sendWindow() {
-        return sendWindow;
-    }
-
-    static String keyFor(HttpConnection connection) {
-        boolean isProxy = connection.isProxied();
-        boolean isSecure = connection.isSecure();
-        InetSocketAddress addr = connection.address();
-
-        return keyString(isSecure, isProxy, addr.getHostString(), addr.getPort());
-    }
-
-    static String keyFor(URI uri, InetSocketAddress proxy) {
-        boolean isSecure = uri.getScheme().equalsIgnoreCase("https");
-        boolean isProxy = proxy != null;
-
-        String host;
-        int port;
-
-        if (isProxy) {
-            host = proxy.getHostString();
-            port = proxy.getPort();
-        } else {
-            host = uri.getHost();
-            port = uri.getPort();
-        }
-        return keyString(isSecure, isProxy, host, port);
-    }
-
-    // {C,S}:{H:P}:host:port
-    // C indicates clear text connection "http"
-    // S indicates secure "https"
-    // H indicates host (direct) connection
-    // P indicates proxy
-    // Eg: "S:H:foo.com:80"
-    static String keyString(boolean secure, boolean proxy, String host, int port) {
-        char c1 = secure ? 'S' : 'C';
-        char c2 = proxy ? 'P' : 'H';
-
-        StringBuilder sb = new StringBuilder(128);
-        sb.append(c1).append(':').append(c2).append(':')
-                .append(host).append(':').append(port);
-        return sb.toString();
-    }
-
-    String key() {
-        return this.key;
-    }
-
-    void putConnection() {
-        client2.putConnection(this);
-    }
-
-    private static String toHexdump1(ByteBuffer bb) {
-        bb.mark();
-        StringBuilder sb = new StringBuilder(512);
-        Formatter f = new Formatter(sb);
-
-        while (bb.hasRemaining()) {
-            int i =  Byte.toUnsignedInt(bb.get());
-            f.format("%02x:", i);
-        }
-        sb.deleteCharAt(sb.length()-1);
-        bb.reset();
-        return sb.toString();
-    }
-
-    private static String toHexdump(ByteBuffer bb) {
-        List<String> words = new ArrayList<>();
-        int i = 0;
-        bb.mark();
-        while (bb.hasRemaining()) {
-            if (i % 2 == 0) {
-                words.add("");
-            }
-            byte b = bb.get();
-            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
-            words.set(i / 2, words.get(i / 2) + hex);
-            i++;
-        }
-        bb.reset();
-        return words.stream().collect(Collectors.joining(" "));
-    }
-
-    private void decodeHeaders(HeaderFrame frame, DecodingCallback decoder) {
-        boolean endOfHeaders = frame.getFlag(HeaderFrame.END_HEADERS);
-
-        ByteBuffer[] buffers = frame.getHeaderBlock();
-        for (int i = 0; i < buffers.length; i++) {
-            hpackIn.decode(buffers[i], endOfHeaders && (i == buffers.length - 1), decoder);
-        }
-    }
-
-    int getInitialSendWindowSize() {
-        return serverSettings.getParameter(SettingsFrame.INITIAL_WINDOW_SIZE);
-    }
-
-    void close() {
-        GoAwayFrame f = new GoAwayFrame();
-        f.setDebugData("Requested by user".getBytes());
-        // TODO: set last stream. For now zero ok.
-        sendFrame(f);
-    }
-
-    // BufferHandler methods
-
-    @Override
-    public ByteBuffer getBuffer(int n) {
-        return client.getBuffer(n);
-    }
-
-    @Override
-    public void returnBuffer(ByteBuffer buf) {
-        client.returnBuffer(buf);
-    }
-
-    @Override
-    public void setMinBufferSize(int n) {
-        client.setMinBufferSize(n);
-    }
-
-    private final Object readlock = new Object();
-
-    void asyncReceive(ByteBuffer buffer) {
-        synchronized (readlock) {
-            try {
-                if (reader == null) {
-                    reader = new FrameReader(buffer);
-                } else {
-                    reader.input(buffer);
-                }
-                while (true) {
-                    if (reader.haveFrame()) {
-                        List<ByteBuffer> buffers = reader.frame();
-
-                        ByteBufferConsumer bbc = new ByteBufferConsumer(buffers, this::getBuffer);
-                        processFrame(bbc);
-                        if (bbc.consumed()) {
-                            reader = new FrameReader();
-                            return;
-                        } else {
-                            reader = new FrameReader(reader);
-                        }
-                    } else
-                        return;
-                }
-            } catch (Throwable e) {
-                String msg = Utils.stackTrace(e);
-                Log.logTrace(msg);
-                shutdown(e);
-            }
-        }
-    }
-
-    void shutdown(Throwable t) {
-        Log.logError(t);
-        closed = true;
-        client2.deleteConnection(this);
-        List<Stream> c = new LinkedList<>(streams.values());
-        for (Stream s : c) {
-            s.cancelImpl(t);
-        }
-        connection.close();
-    }
-
-    /**
-     * Handles stream 0 (common) frames that apply to whole connection and passes
-     * other stream specific frames to that Stream object.
-     *
-     * Invokes Stream.incoming() which is expected to process frame without
-     * blocking.
-     */
-    void processFrame(ByteBufferConsumer bbc) throws IOException, InterruptedException {
-        Http2Frame frame = Http2Frame.readIncoming(bbc);
-        Log.logFrames(frame, "IN");
-        int streamid = frame.streamid();
-        if (streamid == 0) {
-            handleCommonFrame(frame);
-        } else {
-            Stream stream = getStream(streamid);
-            if (stream == null) {
-                // should never receive a frame with unknown stream id
-                resetStream(streamid, ResetFrame.PROTOCOL_ERROR);
-            }
-            if (frame instanceof PushPromiseFrame) {
-                PushPromiseFrame pp = (PushPromiseFrame)frame;
-                handlePushPromise(stream, pp);
-            } else if (frame instanceof HeaderFrame) {
-                // decode headers (or continuation)
-                decodeHeaders((HeaderFrame) frame, stream.rspHeadersConsumer());
-                stream.incoming(frame);
-            } else
-                stream.incoming(frame);
-        }
-    }
-
-    private void handlePushPromise(Stream parent, PushPromiseFrame pp)
-            throws IOException, InterruptedException {
-
-        HttpRequestImpl parentReq = parent.request;
-        int promisedStreamid = pp.getPromisedStream();
-        if (promisedStreamid != nextPushStream) {
-            resetStream(promisedStreamid, ResetFrame.PROTOCOL_ERROR);
-            return;
-        } else {
-            nextPushStream += 2;
-        }
-        HeaderDecoder decoder = new HeaderDecoder();
-        decodeHeaders(pp, decoder);
-        HttpHeadersImpl headers = decoder.headers();
-        HttpRequestImpl pushReq = HttpRequestImpl.createPushRequest(parentReq, headers);
-
-        Stream.PushedStream pushStream = createPushStream(parent, pushReq);
-        pushStream.registerStream(promisedStreamid);
-        parent.incoming_pushPromise(pushReq, pushStream);
-    }
-
-    private void handleCommonFrame(Http2Frame frame)
-            throws IOException, InterruptedException {
-
-        switch (frame.type()) {
-          case SettingsFrame.TYPE:
-          { SettingsFrame f = (SettingsFrame)frame;
-            handleSettings(f);}
-            break;
-          case PingFrame.TYPE:
-          { PingFrame f = (PingFrame)frame;
-            handlePing(f);}
-            break;
-          case GoAwayFrame.TYPE:
-          { GoAwayFrame f = (GoAwayFrame)frame;
-            handleGoAway(f);}
-            break;
-          case WindowUpdateFrame.TYPE:
-          { WindowUpdateFrame f = (WindowUpdateFrame)frame;
-            handleWindowUpdate(f);}
-            break;
-          default:
-            protocolError(ErrorFrame.PROTOCOL_ERROR);
-        }
-    }
-
-    void resetStream(int streamid, int code) throws IOException, InterruptedException {
-        Log.logError(
-            "Resetting stream {0,number,integer} with error code {1,number,integer}",
-            streamid, code);
-        ResetFrame frame = new ResetFrame();
-        frame.streamid(streamid);
-        frame.setErrorCode(code);
-        sendFrame(frame);
-        streams.remove(streamid);
-    }
-
-    private void handleWindowUpdate(WindowUpdateFrame f)
-            throws IOException, InterruptedException {
-        updateSendWindow(f.getUpdate());
-    }
-
-    private void protocolError(int errorCode)
-            throws IOException, InterruptedException {
-        GoAwayFrame frame = new GoAwayFrame();
-        frame.setErrorCode(errorCode);
-        sendFrame(frame);
-        String msg = "Error code: " + errorCode;
-        shutdown(new IOException("protocol error"));
-    }
-
-    private void handleSettings(SettingsFrame frame)
-            throws IOException, InterruptedException {
-        if (frame.getFlag(SettingsFrame.ACK)) {
-            // ignore ack frames for now.
-            return;
-        }
-        serverSettings = frame;
-        SettingsFrame ack = getAckFrame(frame.streamid());
-        sendFrame(ack);
-    }
-
-    private void handlePing(PingFrame frame)
-            throws IOException, InterruptedException {
-        frame.setFlag(PingFrame.ACK);
-        sendFrame(frame);
-    }
-
-    private void handleGoAway(GoAwayFrame frame)
-            throws IOException, InterruptedException {
-        //System.err.printf("GoAWAY: %s\n", ErrorFrame.stringForCode(frame.getErrorCode()));
-        shutdown(new IOException("GOAWAY received"));
-    }
-
-    private void initCommon() {
-        clientSettings = client2.getClientSettings();
-
-        // serverSettings will be updated by server
-        serverSettings = SettingsFrame.getDefaultSettings();
-        hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
-        hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE));
-    }
-
-    /**
-     * Max frame size we are allowed to send
-     */
-    public int getMaxSendFrameSize() {
-        int param = serverSettings.getParameter(MAX_FRAME_SIZE);
-        if (param == -1) {
-            param = DEFAULT_FRAME_SIZE;
-        }
-        return param;
-    }
-
-    /**
-     * Max frame size we will receive
-     */
-    public int getMaxReceiveFrameSize() {
-        return clientSettings.getParameter(MAX_FRAME_SIZE);
-    }
-
-    // Not sure how useful this is.
-    public int getMaxHeadersSize() {
-        return serverSettings.getParameter(MAX_HEADER_LIST_SIZE);
-    }
-
-    private static final String CLIENT_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
-
-    private static final byte[] PREFACE_BYTES =
-        CLIENT_PREFACE.getBytes(StandardCharsets.ISO_8859_1);
-
-    /**
-     * Sends Connection preface and Settings frame with current preferred
-     * values
-     */
-    private void sendConnectionPreface() throws IOException {
-        ByteBufferGenerator bg = new ByteBufferGenerator(this);
-        bg.getBuffer(PREFACE_BYTES.length).put(PREFACE_BYTES);
-        ByteBuffer[] ba = bg.getBufferArray();
-        connection.write(ba, 0, ba.length);
-
-        bg = new ByteBufferGenerator(this);
-        SettingsFrame sf = client2.getClientSettings();
-        Log.logFrames(sf, "OUT");
-        sf.writeOutgoing(bg);
-        WindowUpdateFrame wup = new WindowUpdateFrame();
-        wup.streamid(0);
-        // send a Window update for the receive buffer we are using
-        // minus the initial 64 K specified in protocol
-        wup.setUpdate(client2.client().getReceiveBufferSize() - (64 * 1024 - 1));
-        wup.computeLength();
-        wup.writeOutgoing(bg);
-        Log.logFrames(wup, "OUT");
-        ba = bg.getBufferArray();
-        connection.write(ba, 0, ba.length);
-    }
-
-    /**
-     * Returns an existing Stream with given id, or null if doesn't exist
-     */
-    Stream getStream(int streamid) {
-        return streams.get(streamid);
-    }
-
-    /**
-     * Creates Stream with given id.
-     */
-    Stream createStream(Exchange exchange) {
-        Stream stream = new Stream(client, this, exchange);
-        return stream;
-    }
-
-    Stream.PushedStream createPushStream(Stream parent, HttpRequestImpl pushReq) {
-        Stream.PushGroup<?> pg = parent.request.pushGroup();
-        return new Stream.PushedStream(pg, client, this, parent, pushReq);
-    }
-
-    void putStream(Stream stream, int streamid) {
-        streams.put(streamid, stream);
-    }
-
-    void deleteStream(Stream stream) {
-        streams.remove(stream.streamid);
-    }
-
-    static final int MAX_STREAM = Integer.MAX_VALUE - 2;
-
-    // Number of header bytes in a Headers Frame
-    final static int HEADERS_HEADER_SIZE = 15;
-
-    // Number of header bytes in a Continuation frame
-    final static int CONTIN_HEADER_SIZE = 9;
-
-    /**
-     * Encode the headers into a List<ByteBuffer> and then create HEADERS
-     * and CONTINUATION frames from the list and return the List<Http2Frame>.
-     *
-     * @param frame
-     * @return
-     */
-    private LinkedList<Http2Frame> encodeHeaders(OutgoingHeaders frame) {
-        LinkedList<ByteBuffer> buffers = new LinkedList<>();
-        ByteBuffer buf = getBuffer();
-        buffers.add(buf);
-        encodeHeadersImpl(frame.stream.getRequestPseudoHeaders(), buffers);
-        encodeHeadersImpl(frame.getUserHeaders(), buffers);
-        encodeHeadersImpl(frame.getSystemHeaders(), buffers);
-
-        for (ByteBuffer b : buffers) {
-            b.flip();
-        }
-
-        LinkedList<Http2Frame> frames = new LinkedList<>();
-        int maxframesize = getMaxSendFrameSize();
-
-        HeadersFrame oframe = new HeadersFrame();
-        oframe.setFlags(frame.getFlags());
-        oframe.streamid(frame.streamid());
-
-        oframe.setHeaderBlock(getBufferArray(buffers, maxframesize));
-        frames.add(oframe);
-        // Any buffers left?
-        boolean done = buffers.isEmpty();
-        if (done) {
-            oframe.setFlag(HeaderFrame.END_HEADERS);
-        } else {
-            ContinuationFrame cf = null;
-            while (!done) {
-                cf = new ContinuationFrame();
-                cf.streamid(frame.streamid());
-                cf.setHeaderBlock(getBufferArray(buffers, maxframesize));
-                frames.add(cf);
-                done = buffers.isEmpty();
-            }
-            cf.setFlag(HeaderFrame.END_HEADERS);
-        }
-        return frames;
-    }
-
-    // should always return at least one buffer
-    private static ByteBuffer[] getBufferArray(LinkedList<ByteBuffer> list, int maxsize) {
-        assert maxsize >= BUFSIZE;
-        LinkedList<ByteBuffer> newlist = new LinkedList<>();
-        int size = list.size();
-        int nbytes = 0;
-        for (int i=0; i<size; i++) {
-            ByteBuffer buf = list.getFirst();
-            if (nbytes + buf.remaining() <= maxsize) {
-                nbytes += buf.remaining();
-                newlist.add(buf);
-                list.remove();
-            } else {
-                break;
-            }
-        }
-        return newlist.toArray(empty);
-    }
-
-    /**
-     * Encode all the headers from the given HttpHeadersImpl into the given List.
-     */
-    private void encodeHeadersImpl(HttpHeaders hdrs, LinkedList<ByteBuffer> buffers) {
-        ByteBuffer buffer;
-        if (!(buffer = buffers.getLast()).hasRemaining()) {
-            buffer = getBuffer();
-            buffers.add(buffer);
-        }
-        for (Map.Entry<String, List<String>> e : hdrs.map().entrySet()) {
-            String key = e.getKey();
-            String lkey = key.toLowerCase();
-            List<String> values = e.getValue();
-            for (String value : values) {
-                hpackOut.header(lkey, value);
-                boolean encoded = false;
-                do {
-                    encoded = hpackOut.encode(buffer);
-                    if (!encoded) {
-                        buffer = getBuffer();
-                        buffers.add(buffer);
-                    }
-                } while (!encoded);
-            }
-        }
-    }
-
-    public void sendFrames(List<Http2Frame> frames) throws IOException, InterruptedException {
-        for (Http2Frame frame : frames) {
-            sendFrame(frame);
-        }
-    }
-
-    static Throwable getExceptionFrom(CompletableFuture<?> cf) {
-        try {
-            cf.get();
-            return null;
-        } catch (Throwable e) {
-            if (e.getCause() != null)
-                return e.getCause();
-            else
-                return e;
-        }
-    }
-
-
-    void execute(Runnable r) {
-        executor.execute(r, null);
-    }
-
-    private final Object sendlock = new Object();
-
-    /**
-     *
-     */
-    void sendFrame(Http2Frame frame) {
-        synchronized (sendlock) {
-            try {
-                if (frame instanceof OutgoingHeaders) {
-                    OutgoingHeaders oh = (OutgoingHeaders) frame;
-                    Stream stream = oh.getStream();
-                    stream.registerStream(nextstreamid);
-                    oh.streamid(nextstreamid);
-                    nextstreamid += 2;
-                    // set outgoing window here. This allows thread sending
-                    // body to proceed.
-                    stream.updateOutgoingWindow(getInitialSendWindowSize());
-                    LinkedList<Http2Frame> frames = encodeHeaders(oh);
-                    for (Http2Frame f : frames) {
-                        sendOneFrame(f);
-                    }
-                } else {
-                    sendOneFrame(frame);
-                }
-
-            } catch (IOException e) {
-                if (!closed) {
-                    Log.logError(e);
-                    shutdown(e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Send a frame.
-     *
-     * @param frame
-     * @throws IOException
-     */
-    private void sendOneFrame(Http2Frame frame) throws IOException {
-        ByteBufferGenerator bbg = new ByteBufferGenerator(this);
-        frame.computeLength();
-        Log.logFrames(frame, "OUT");
-        frame.writeOutgoing(bbg);
-        ByteBuffer[] currentBufs = bbg.getBufferArray();
-        connection.write(currentBufs, 0, currentBufs.length);
-    }
-
-
-    private SettingsFrame getAckFrame(int streamid) {
-        SettingsFrame frame = new SettingsFrame();
-        frame.setFlag(SettingsFrame.ACK);
-        frame.streamid(streamid);
-        return frame;
-    }
-
-    static class HeaderDecoder implements DecodingCallback {
-        HttpHeadersImpl headers;
-
-        HeaderDecoder() {
-            this.headers = new HttpHeadersImpl();
-        }
-
-        @Override
-        public void onDecoded(CharSequence name, CharSequence value) {
-            headers.addHeader(name.toString(), value.toString());
-        }
-
-        HttpHeadersImpl headers() {
-            return headers;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http2Frame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-/**
- * When sending a frame, the length field must be set in sub-class
- * by calling computeLength()
- */
-abstract class Http2Frame {
-
-    int length = -1;
-    int type;
-    int streamid;
-    int flags;
-
-    // called when reading in only
-    void initCommon(int length, int type, int streamid, int flags) {
-        this.length = length;
-        this.type = type;
-        this.streamid = streamid;
-        this.flags = flags;
-    }
-
-    public int length() {
-        return length;
-    }
-
-    public int type() {
-        return type;
-    }
-
-    public int streamid() {
-        return streamid;
-    }
-
-    public void setFlag(int flag) {
-        flags |= flag;
-    }
-
-    public void setFlags(int flags) {
-        this.flags = flags;
-    }
-
-    public int getFlags() {
-        return flags;
-    }
-
-    public boolean getFlag(int flag) {
-        return (flags & flag) != 0;
-    }
-
-    public void clearFlag(int flag) {
-        flags &= 0xffffffff ^ flag;
-    }
-
-    public void streamid(int streamid) {
-        this.streamid = streamid;
-    }
-
-    abstract void readIncomingImpl(ByteBufferConsumer bc) throws IOException;
-
-    /**
-     * assume given array contains at least one complete frame.
-     */
-    static Http2Frame readIncoming(ByteBufferConsumer bc) throws IOException {
-        int x = bc.getInt();
-        int length = x >> 8;
-        int type = x & 0xff;
-        int flags = bc.getByte();
-        int streamid = bc.getInt();
-        Http2Frame f = null;
-        switch (type) {
-          case DataFrame.TYPE:
-            f = new DataFrame();
-            break;
-          case HeadersFrame.TYPE:
-            f = new HeadersFrame();
-            break;
-          case ContinuationFrame.TYPE:
-            f = new ContinuationFrame();
-            break;
-          case ResetFrame.TYPE:
-            f = new ResetFrame();
-            break;
-          case PriorityFrame.TYPE:
-            f = new PriorityFrame();
-            break;
-          case SettingsFrame.TYPE:
-            f = new SettingsFrame();
-            break;
-          case GoAwayFrame.TYPE:
-            f = new GoAwayFrame();
-            break;
-          case PingFrame.TYPE:
-            f = new PingFrame();
-            break;
-          case PushPromiseFrame.TYPE:
-            f = new PushPromiseFrame();
-            break;
-          case WindowUpdateFrame.TYPE:
-            f = new WindowUpdateFrame();
-            break;
-          default:
-            String msg = Integer.toString(type);
-            throw new IOException("unknown frame type " + msg);
-        }
-        f.initCommon(length, type, streamid, flags);
-        f.readIncomingImpl(bc);
-        return f;
-    }
-
-    public String typeAsString() {
-        return asString(this.type);
-    }
-
-    public static String asString(int type) {
-        switch (type) {
-          case DataFrame.TYPE:
-            return "DATA";
-          case HeadersFrame.TYPE:
-            return "HEADERS";
-          case ContinuationFrame.TYPE:
-            return "CONTINUATION";
-          case ResetFrame.TYPE:
-            return "RESET";
-          case PriorityFrame.TYPE:
-            return "PRIORITY";
-          case SettingsFrame.TYPE:
-            return "SETTINGS";
-          case GoAwayFrame.TYPE:
-            return "GOAWAY";
-          case PingFrame.TYPE:
-            return "PING";
-          case PushPromiseFrame.TYPE:
-            return "PUSH_PROMISE";
-          case WindowUpdateFrame.TYPE:
-            return "WINDOW_UPDATE";
-          default:
-            return "UNKNOWN";
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(typeAsString())
-                .append(": length=")
-                .append(Integer.toString(length))
-                .append(", streamid=")
-                .append(streamid)
-                .append(", flags=");
-
-        int f = flags;
-        int i = 0;
-        if (f == 0) {
-            sb.append("0 ");
-        } else {
-            while (f != 0) {
-                if ((f & 1) == 1) {
-                    sb.append(flagAsString(1 << i))
-                      .append(' ');
-                }
-                f = f >> 1;
-                i++;
-            }
-        }
-        return sb.toString();
-    }
-
-    // Override
-    String flagAsString(int f) {
-        return "unknown";
-    }
-
-    abstract void computeLength();
-
-    void writeOutgoing(ByteBufferGenerator bg) {
-        if (length == -1) {
-            throw new InternalError("Length not set on outgoing frame");
-        }
-        ByteBuffer buf = bg.getBuffer(9);
-        int x = (length << 8) + type;
-        buf.putInt(x);
-        buf.put((byte)flags);
-        buf.putInt(streamid);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClient.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,415 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.Authenticator;
-import java.net.CookieManager;
-import java.net.InetSocketAddress;
-import java.net.NetPermission;
-import java.net.ProxySelector;
-import java.net.URI;
-import java.util.Optional;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
-
-/**
- * A container for configuration information common to multiple {@link
- * HttpRequest}s. All requests are associated with, and created from a {@code
- * HttpClient}.
- *
- * <p> {@code HttpClient}s are immutable and created from a builder returned
- * from {@link HttpClient#create()}. Request builders that are associated with
- * an application created client, are created by calling {@link #request(URI) }.
- * It is also possible to create a request builder directly which is associated
- * with the <i>default</i> {@code HttpClient} by calling {@link
- * HttpRequest#create(URI)}.
- *
- * <p> The HTTP API functions asynchronously (using {@link
- * java.util.concurrent.CompletableFuture}) and also in a simple synchronous
- * mode, where all work may be done on the calling thread. In asynchronous mode,
- * work is done on the threads supplied by the client's {@link
- * java.util.concurrent.ExecutorService}.
- *
- * <p> <a name="defaultclient"></a> The <i>default</i> {@code HttpClient} is
- * used whenever a request is created without specifying a client explicitly
- * (by calling {@link HttpRequest#create(java.net.URI) HttpRequest.create}).
- * There is only one static instance of this {@code HttpClient}. A reference to
- * the default client can be obtained by calling {@link #getDefault() }. If a
- * security manager is set, then a permission is required for this.
- *
- * <p> See {@link HttpRequest} for examples of usage of this API.
- *
- * @since 9
- */
-public abstract class HttpClient {
-
-    HttpClient() {}
-
-    private static HttpClient defaultClient;
-
-    /**
-     * Creates a new {@code HttpClient} builder.
-     *
-     * @return a {@code HttpClient.Builder}
-     */
-    public static Builder  create() {
-        return new HttpClientBuilderImpl();
-    }
-
-    //public abstract void debugPrint();
-
-    /**
-     * Returns the default {@code HttpClient} that is used when a {@link
-     * HttpRequest} is created without specifying a client. If a security
-     * manager is set, then its {@code checkPermission} method is called with a
-     * {@link java.net.NetPermission} specifying the name "getDefaultHttpClient".
-     * If the caller does not possess this permission a {@code SecurityException}
-     * is thrown.
-     *
-     * @implNote Code running under a security manager can avoid the security
-     * manager check by creating a {@code HttpClient} explicitly.
-     *
-     * @return the default {@code HttpClient}
-     * @throws SecurityException if the caller does not have the required
-     *                           permission
-     */
-    public synchronized static HttpClient getDefault() {
-        Utils.checkNetPermission("getDefaultHttpClient");
-        if (defaultClient == null) {
-            Builder b = create();
-            defaultClient = b.executorService(Executors.newCachedThreadPool())
-                             .build();
-        }
-        return defaultClient;
-    }
-
-    /**
-     * Creates a {@code HttpRequest} builder associated with this client.
-     *
-     * @return a new builder
-     */
-    public abstract HttpRequest.Builder request();
-
-    /**
-     * Creates a {@code HttpRequest} builder associated with this client and
-     * using the given request URI.
-     *
-     * @param uri the request URI
-     * @return a new builder
-     */
-    public abstract HttpRequest.Builder request(URI uri);
-
-    /**
-     * A builder of immutable {@link HttpClient}s. {@code HttpClient.Builder}s
-     * are created by calling {@link HttpClient#create()}.
-     *
-     * <p> Each of the setter methods in this class modifies the state of the
-     * builder and returns <i>this</i> (ie. the same instance). The methods are
-     * not synchronized and should not be called from multiple threads without
-     * external synchronization.
-     *
-     * <p> {@link #build() } returns a new {@code HttpClient} each time it is
-     * called.
-     *
-     * @since 9
-     */
-    public abstract static class Builder {
-
-        Builder() {}
-
-        /**
-         * Sets a cookie manager.
-         *
-         * @param manager the CookieManager
-         * @return this builder
-         * @throws NullPointerException if {@code manager} is null
-         */
-        public abstract Builder cookieManager(CookieManager manager);
-
-        /**
-         * Sets an SSLContext. If a security manager is set, then the caller
-         * must have the {@link java.net.NetPermission NetPermission}
-         * ("setSSLContext")
-         *
-         * <p> The effect of not calling this method, is that a default {@link
-         * javax.net.ssl.SSLContext} is used, which is normally adequate for
-         * client applications that do not need to specify protocols, or require
-         * client authentication.
-         *
-         * @param sslContext the SSLContext
-         * @return this builder
-         * @throws NullPointerException if {@code sslContext} is null
-         * @throws SecurityException if a security manager is set and the
-         *                           caller does not have any required permission
-         */
-        public abstract Builder sslContext(SSLContext sslContext);
-
-        /**
-         * Sets an SSLParameters. If this method is not called, then a default
-         * set of parameters are used. The contents of the given object are
-         * copied. Some parameters which are used internally by the HTTP protocol
-         * implementation (such as application protocol list) should not be set
-         * by callers, as they are ignored.
-         *
-         * @param sslParameters the SSLParameters
-         * @return this builder
-         * @throws NullPointerException if {@code sslParameters} is null
-         */
-        public abstract Builder sslParameters(SSLParameters sslParameters);
-
-        /**
-         * Sets the ExecutorService to be used for sending and receiving
-         * asynchronous requests. If this method is not called, a default
-         * executor service is set, which is the one returned from {@link
-         * java.util.concurrent.Executors#newCachedThreadPool()
-         * Executors.newCachedThreadPool}.
-         *
-         * @param s the ExecutorService
-         * @return this builder
-         * @throws NullPointerException if {@code s} is null
-         */
-        public abstract Builder executorService(ExecutorService s);
-
-        /**
-         * Specifies whether requests will automatically follow redirects issued
-         * by the server. This setting can be overridden on each request. The
-         * default value for this setting is {@link Redirect#NEVER NEVER}
-         *
-         * @param policy the redirection policy
-         * @return this builder
-         * @throws NullPointerException if {@code policy} is null
-         */
-        public abstract Builder followRedirects(Redirect policy);
-
-        /**
-         * Requests a specific HTTP protocol version where possible. If not set,
-         * the version defaults to {@link HttpClient.Version#HTTP_1_1}. If
-         * {@link HttpClient.Version#HTTP_2} is set, then each request will
-         * attempt to upgrade to HTTP/2.  If the upgrade succeeds, then the
-         * response to this request will use HTTP/2 and all subsequent requests
-         * and responses to the same
-         * <a href="https://tools.ietf.org/html/rfc6454#section-4">origin server</a>
-         * will use HTTP/2. If the upgrade fails, then the response will be
-         * handled using HTTP/1.1
-         *
-         * <p>This setting can be over-ridden per request.
-         *
-         * @param version the requested HTTP protocol version
-         * @return this builder
-         * @throws NullPointerException if {@code version} is null
-         */
-        public abstract Builder version(HttpClient.Version version);
-
-        /**
-         * Sets the default priority for any HTTP/2 requests sent from this
-         * client. The value provided must be between {@code 1} and {@code 255}.
-         *
-         * @param priority the priority weighting
-         * @return this builder
-         * @throws IllegalArgumentException if the given priority is out of range
-         */
-        public abstract Builder priority(int priority);
-
-        /**
-         * Enables pipelining mode for HTTP/1.1 requests sent through this
-         * client. When pipelining is enabled requests to the same destination
-         * are sent over existing TCP connections that may already have requests
-         * outstanding. This reduces the number of connections, but may have
-         * a performance impact since responses must be delivered in the same
-         * order that they were sent. By default, pipelining is disabled.
-         *
-         * @param enable {@code true} enables pipelining
-         * @return this builder
-         * @throws UnsupportedOperationException if pipelining mode is not
-         *                                       supported by this implementation
-         */
-        public abstract Builder pipelining(boolean enable);
-
-        /**
-         * Sets a {@link java.net.ProxySelector} for this client. If no selector
-         * is set, then no proxies are used. If a {@code null} parameter is
-         * given then the system wide default proxy selector is used.
-         *
-         * @implNote {@link java.net.ProxySelector#of(InetSocketAddress)}
-         * provides a ProxySelector which uses one proxy for all requests.
-         *
-         * @param selector the ProxySelector
-         * @return this builder
-         */
-        public abstract Builder proxy(ProxySelector selector);
-
-        /**
-         * Sets an authenticator to use for HTTP authentication.
-         *
-         * @param a the Authenticator
-         * @return this builder
-         */
-        public abstract Builder authenticator(Authenticator a);
-
-        /**
-         * Returns a {@link HttpClient} built from the current state of this
-         * builder.
-         *
-         * @return this builder
-         */
-        public abstract HttpClient build();
-    }
-
-
-    /**
-     * Returns an {@code Optional} which contains this client's {@link
-     * CookieManager}. If no CookieManager was set in this client's builder,
-     * then the {@code Optional} is empty.
-     *
-     * @return an {@code Optional} containing this client's CookieManager
-     */
-    public abstract Optional<CookieManager> cookieManager();
-
-    /**
-     * Returns the follow-redirects setting for this client. The default value
-     * for this setting is {@link HttpClient.Redirect#NEVER}
-     *
-     * @return this client's follow redirects setting
-     */
-    public abstract Redirect followRedirects();
-
-    /**
-     * Returns an {@code Optional} containing the ProxySelector for this client.
-     * If no proxy is set then the {@code Optional} is empty.
-     *
-     * @return an {@code Optional} containing this client's proxy selector
-     */
-    public abstract Optional<ProxySelector> proxy();
-
-    /**
-     * Returns the SSLContext, if one was set on this client. If a security
-     * manager is set then then caller must then the caller must have the
-     * {@link java.net.NetPermission NetPermission}("getSSLContext") permission.
-     * If no SSLContext was set, then the default context is returned.
-     *
-     * @return this client's SSLContext
-     */
-    public abstract SSLContext sslContext();
-
-    /**
-     * Returns an {@code Optional} containing the {@link SSLParameters} set on
-     * this client. If no {@code SSLParameters} were set in the client's builder,
-     * then the {@code Optional} is empty.
-     *
-     * @return an {@code Optional} containing this client's SSLParameters
-     */
-    public abstract Optional<SSLParameters> sslParameters();
-
-    /**
-     * Returns an {@code Optional} containing the {@link Authenticator} set on
-     * this client. If no {@code Authenticator} was set in the client's builder,
-     * then the {@code Optional} is empty.
-     *
-     * @return an {@code Optional} containing this client's Authenticator
-     */
-    public abstract Optional<Authenticator> authenticator();
-
-    /**
-     * Returns the HTTP protocol version requested for this client. The default
-     * value is {@link HttpClient.Version#HTTP_1_1}
-     *
-     * @return the HTTP protocol version requested
-     */
-    public abstract HttpClient.Version version();
-
-    /**
-     * Returns whether this client supports HTTP/1.1 pipelining.
-     *
-     * @return whether pipelining allowed
-     */
-    public abstract boolean pipelining();
-
-    /**
-     * Returns the {@code ExecutorService} set on this client. If an {@code
-     * ExecutorService} was not set on the client's builder, then a default
-     * object is returned. The default ExecutorService is created independently
-     * for each client.
-     *
-     * @return this client's ExecutorService
-     */
-    public abstract ExecutorService executorService();
-
-    /**
-     * The HTTP protocol version.
-     *
-     * @since 9
-     */
-    public static enum Version {
-
-        /**
-         * HTTP version 1.1
-         */
-        HTTP_1_1,
-
-        /**
-         * HTTP version 2
-         */
-        HTTP_2
-    }
-
-    /**
-     * Defines automatic redirection policy. This is checked whenever a 3XX
-     * response code is received. If redirection does not happen automatically
-     * then the response is returned to the user, where it can be handled
-     * manually.
-     *
-     * <p> {@code Redirect} policy is set via the {@link
-     * HttpClient.Builder#followRedirects(HttpClient.Redirect)} method.
-     *
-     * @since 9
-     */
-    public static enum Redirect {
-
-        /**
-         * Never redirect.
-         */
-        NEVER,
-
-        /**
-         * Always redirect.
-         */
-        ALWAYS,
-
-        /**
-         * Redirect to same protocol only. Redirection may occur from HTTP URLs
-         * to other HTTP URLs, and from HTTPS URLs to other HTTPS URLs.
-         */
-        SAME_PROTOCOL,
-
-        /**
-         * Redirect always except from HTTPS URLs to HTTP URLs.
-         */
-        SECURE
-    }
-
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientBuilderImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.Authenticator;
-import java.net.CookieManager;
-import java.net.ProxySelector;
-import java.util.Objects;
-import java.util.concurrent.ExecutorService;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
-
-class HttpClientBuilderImpl extends HttpClient.Builder {
-
-    CookieManager cookieManager;
-    HttpClient.Redirect followRedirects;
-    ProxySelector proxy;
-    Authenticator authenticator;
-    HttpClient.Version version = HttpClient.Version.HTTP_1_1;
-    ExecutorService executor;
-    // Security parameters
-    SSLContext sslContext;
-    SSLParameters sslParams;
-    int priority = -1;
-
-    @Override
-    public HttpClientBuilderImpl cookieManager(CookieManager manager) {
-        Objects.requireNonNull(manager);
-        this.cookieManager = manager;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl sslContext(SSLContext sslContext) {
-        Objects.requireNonNull(sslContext);
-        Utils.checkNetPermission("setSSLContext");
-        this.sslContext = sslContext;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl sslParameters(SSLParameters sslParameters) {
-        Objects.requireNonNull(sslParameters);
-        this.sslParams = sslParameters;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl executorService(ExecutorService s) {
-        Objects.requireNonNull(s);
-        this.executor = s;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl followRedirects(HttpClient.Redirect policy) {
-        Objects.requireNonNull(policy);
-        this.followRedirects = policy;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl version(HttpClient.Version version) {
-        Objects.requireNonNull(version);
-        this.version = version;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl priority(int priority) {
-        if (priority < 1 || priority > 255) {
-            throw new IllegalArgumentException("priority must be between 1 and 255");
-        }
-        this.priority = priority;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl pipelining(boolean enable) {
-        //To change body of generated methods, choose Tools | Templates.
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl proxy(ProxySelector proxy) {
-        Objects.requireNonNull(proxy);
-        this.proxy = proxy;
-        return this;
-    }
-
-
-    @Override
-    public HttpClientBuilderImpl authenticator(Authenticator a) {
-        Objects.requireNonNull(a);
-        this.authenticator = a;
-        return this;
-    }
-
-    @Override
-    public HttpClient build() {
-        return HttpClientImpl.create(this);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,591 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
-import java.io.IOException;
-import java.net.Authenticator;
-import java.net.CookieManager;
-import java.net.ProxySelector;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.stream.Stream;
-
-import static java.net.http.Utils.BUFSIZE;
-
-/**
- * Client implementation. Contains all configuration information and also
- * the selector manager thread which allows async events to be registered
- * and delivered when they occur. See AsyncEvent.
- */
-class HttpClientImpl extends HttpClient implements BufferHandler {
-
-    private static final ThreadFactory defaultFactory =
-            (r -> new Thread(null, r, "HttpClient_worker", 0, true));
-
-    private final CookieManager cookieManager;
-    private final Redirect followRedirects;
-    private final ProxySelector proxySelector;
-    private final Authenticator authenticator;
-    private final Version version;
-    private boolean pipelining = false;
-    private final ConnectionPool connections;
-    private final ExecutorWrapper executor;
-    // Security parameters
-    private final SSLContext sslContext;
-    private final SSLParameters sslParams;
-    private final SelectorManager selmgr;
-    private final FilterFactory filters;
-    private final Http2ClientImpl client2;
-    private final LinkedList<TimeoutEvent> timeouts;
-
-    public static HttpClientImpl create(HttpClientBuilderImpl builder) {
-        HttpClientImpl impl = new HttpClientImpl(builder);
-        impl.start();
-        return impl;
-    }
-
-    private HttpClientImpl(HttpClientBuilderImpl builder) {
-        if (builder.sslContext == null) {
-            try {
-                sslContext = SSLContext.getDefault();
-            } catch (NoSuchAlgorithmException ex) {
-                throw new InternalError(ex);
-            }
-        } else {
-            sslContext = builder.sslContext;
-        }
-        ExecutorService ex = builder.executor;
-        if (ex == null) {
-            ex = Executors.newCachedThreadPool((r) -> {
-                Thread t = defaultFactory.newThread(r);
-                t.setDaemon(true);
-                return t;
-            });
-        } else {
-            ex = builder.executor;
-        }
-        client2 = new Http2ClientImpl(this);
-        executor = ExecutorWrapper.wrap(ex);
-        cookieManager = builder.cookieManager;
-        followRedirects = builder.followRedirects == null ?
-                Redirect.NEVER : builder.followRedirects;
-        this.proxySelector = builder.proxy;
-        authenticator = builder.authenticator;
-        version = builder.version;
-        if (builder.sslParams == null)
-            sslParams = getDefaultParams(sslContext);
-        else
-            sslParams = builder.sslParams;
-        connections = new ConnectionPool();
-        connections.start();
-        timeouts = new LinkedList<>();
-        try {
-            selmgr = new SelectorManager();
-        } catch (IOException e) {
-            // unlikely
-            throw new InternalError(e);
-        }
-        selmgr.setDaemon(true);
-        filters = new FilterFactory();
-        initFilters();
-    }
-
-    private void start() {
-        selmgr.start();
-    }
-
-    private static SSLParameters getDefaultParams(SSLContext ctx) {
-        SSLParameters params = ctx.getSupportedSSLParameters();
-        params.setProtocols(new String[]{"TLSv1.2"});
-        return params;
-    }
-
-    /**
-     * Wait for activity on given exchange (assuming blocking = false).
-     * It's a no-op if blocking = true. In particular, the following occurs
-     * in the SelectorManager thread.
-     *
-     *  1) mark the connection non-blocking
-     *  2) add to selector
-     *  3) If selector fires for this exchange then
-     *  4)   - mark connection as blocking
-     *  5)   - call AsyncEvent.handle()
-     *
-     * If exchange needs to block again, then call registerEvent() again
-     */
-    void registerEvent(AsyncEvent exchange) throws IOException {
-        selmgr.register(exchange);
-    }
-
-    /**
-     * Only used from RawChannel to disconnect the channel from
-     * the selector
-     */
-    void cancelRegistration(SocketChannel s) {
-        selmgr.cancel(s);
-    }
-
-
-    Http2ClientImpl client2() {
-        return client2;
-    }
-
-    /**
-     * We keep one size of buffer on free list. That size may increase
-     * depending on demand. If that happens we dispose of free buffers
-     * that are smaller than new size.
-     */
-    private final LinkedList<ByteBuffer> freelist = new LinkedList<>();
-    int currentSize = BUFSIZE;
-
-    @Override
-    public synchronized ByteBuffer getBuffer(int size) {
-
-        ByteBuffer buf;
-        if (size == -1)
-            size = currentSize;
-
-        if (size > currentSize)
-            currentSize = size;
-
-        while (!freelist.isEmpty()) {
-            buf = freelist.removeFirst();
-            if (buf.capacity() < currentSize)
-                continue;
-            buf.clear();
-            return buf;
-        }
-        return ByteBuffer.allocate(size);
-    }
-
-    @Override
-    public synchronized void returnBuffer(ByteBuffer buffer) {
-        freelist.add(buffer);
-    }
-
-    @Override
-    public synchronized void setMinBufferSize(int n) {
-        currentSize = Math.max(n, currentSize);
-    }
-
-    // Main loop for this client's selector
-    private final class SelectorManager extends Thread {
-
-        private final Selector selector;
-        private volatile boolean closed;
-        private final List<AsyncEvent> readyList;
-        private final List<AsyncEvent> registrations;
-
-        SelectorManager() throws IOException {
-            super(null, null, "SelectorManager", 0, false);
-            readyList = new ArrayList<>();
-            registrations = new ArrayList<>();
-            selector = Selector.open();
-        }
-
-        // This returns immediately. So caller not allowed to send/receive
-        // on connection.
-
-        synchronized void register(AsyncEvent e) throws IOException {
-            registrations.add(e);
-            selector.wakeup();
-        }
-
-        synchronized void cancel(SocketChannel e) {
-            SelectionKey key = e.keyFor(selector);
-            if (key != null)
-                key.cancel();
-            selector.wakeup();
-        }
-
-        void wakeupSelector() {
-            selector.wakeup();
-        }
-
-        synchronized void shutdown() {
-            closed = true;
-            try {
-                selector.close();
-            } catch (IOException ignored) { }
-        }
-
-        @Override
-        public void run() {
-            try {
-                while (!Thread.currentThread().isInterrupted()) {
-                    synchronized (this) {
-                        for (AsyncEvent exchange : registrations) {
-                            SelectableChannel c = exchange.channel();
-                            try {
-                                c.configureBlocking(false);
-                                SelectionKey key = c.keyFor(selector);
-                                SelectorAttachment sa;
-                                if (key == null) {
-                                    sa = new SelectorAttachment(c, selector);
-                                } else {
-                                    sa = (SelectorAttachment) key.attachment();
-                                }
-                                sa.register(exchange);
-                            } catch (IOException e) {
-                                Log.logError("HttpClientImpl: " + e);
-                                c.close();
-                                // let the exchange deal with it
-                                handleEvent(exchange);
-                            }
-                        }
-                        registrations.clear();
-                    }
-                    long timeval = getTimeoutValue();
-                    long now = System.currentTimeMillis();
-                    //debugPrint(selector);
-                    int n = selector.select(timeval);
-                    if (n == 0) {
-                        signalTimeouts(now);
-                        continue;
-                    }
-                    Set<SelectionKey> keys = selector.selectedKeys();
-
-                    for (SelectionKey key : keys) {
-                        SelectorAttachment sa = (SelectorAttachment) key.attachment();
-                        int eventsOccurred = key.readyOps();
-                        sa.events(eventsOccurred).forEach(readyList::add);
-                        sa.resetInterestOps(eventsOccurred);
-                    }
-                    selector.selectNow(); // complete cancellation
-                    selector.selectedKeys().clear();
-
-                    for (AsyncEvent exchange : readyList) {
-                        if (exchange.blocking()) {
-                            exchange.channel().configureBlocking(true);
-                        }
-                        executor.synchronize();
-                        handleEvent(exchange); // will be delegated to executor
-                    }
-                    readyList.clear();
-                }
-            } catch (Throwable e) {
-                if (!closed) {
-                    // This terminates thread. So, better just print stack trace
-                    String err = Utils.stackTrace(e);
-                    Log.logError("HttpClientImpl: fatal error: " + err);
-                }
-            } finally {
-                shutdown();
-            }
-        }
-
-        void debugPrint(Selector selector) {
-            System.err.println("Selector: debugprint start");
-            Set<SelectionKey> keys = selector.keys();
-            for (SelectionKey key : keys) {
-                SelectableChannel c = key.channel();
-                int ops = key.interestOps();
-                System.err.printf("selector chan:%s ops:%d\n", c, ops);
-            }
-            System.err.println("Selector: debugprint end");
-        }
-
-        void handleEvent(AsyncEvent e) {
-            if (closed) {
-                e.abort();
-            } else {
-                e.handle();
-            }
-        }
-    }
-
-    /**
-     * Tracks multiple user level registrations associated with one NIO
-     * registration (SelectionKey). In this implementation, registrations
-     * are one-off and when an event is posted the registration is cancelled
-     * until explicitly registered again.
-     *
-     * <p> No external synchronization required as this class is only used
-     * by the SelectorManager thread. One of these objects required per
-     * connection.
-     */
-    private static class SelectorAttachment {
-        private final SelectableChannel chan;
-        private final Selector selector;
-        private final ArrayList<AsyncEvent> pending;
-        private int interestOps;
-
-        SelectorAttachment(SelectableChannel chan, Selector selector) {
-            this.pending = new ArrayList<>();
-            this.chan = chan;
-            this.selector = selector;
-        }
-
-        void register(AsyncEvent e) throws ClosedChannelException {
-            int newOps = e.interestOps();
-            boolean reRegister = (interestOps & newOps) != newOps;
-            interestOps |= newOps;
-            pending.add(e);
-            if (reRegister) {
-                // first time registration happens here also
-                chan.register(selector, interestOps, this);
-            }
-        }
-
-        /**
-         * Returns a Stream<AsyncEvents> containing only events that are
-         * registered with the given {@code interestOps}.
-         */
-        Stream<AsyncEvent> events(int interestOps) {
-            return pending.stream()
-                    .filter(ev -> (ev.interestOps() & interestOps) != 0);
-        }
-
-        /**
-         * Removes any events with the given {@code interestOps}, and if no
-         * events remaining, cancels the associated SelectionKey.
-         */
-        void resetInterestOps(int interestOps) {
-            int newOps = 0;
-
-            Iterator<AsyncEvent> itr = pending.iterator();
-            while (itr.hasNext()) {
-                AsyncEvent event = itr.next();
-                int evops = event.interestOps();
-                if (event.repeating()) {
-                    newOps |= evops;
-                    continue;
-                }
-                if ((evops & interestOps) != 0) {
-                    itr.remove();
-                } else {
-                    newOps |= evops;
-                }
-            }
-
-            this.interestOps = newOps;
-            SelectionKey key = chan.keyFor(selector);
-            if (newOps == 0) {
-                key.cancel();
-            } else {
-                key.interestOps(newOps);
-            }
-        }
-    }
-
-    /**
-     * Creates a HttpRequest associated with this group.
-     *
-     * @throws IllegalStateException
-     *         if the group has been stopped
-     */
-    @Override
-    public HttpRequestBuilderImpl request() {
-        return new HttpRequestBuilderImpl(this, null);
-    }
-
-    /**
-     * Creates a HttpRequest associated with this group.
-     *
-     * @throws IllegalStateException
-     *         if the group has been stopped
-     */
-    @Override
-    public HttpRequestBuilderImpl request(URI uri) {
-        return new HttpRequestBuilderImpl(this, uri);
-    }
-
-    @Override
-    public SSLContext sslContext() {
-        Utils.checkNetPermission("getSSLContext");
-        return sslContext;
-    }
-
-    @Override
-    public Optional<SSLParameters> sslParameters() {
-        return Optional.ofNullable(sslParams);
-    }
-
-    @Override
-    public Optional<Authenticator> authenticator() {
-        return Optional.ofNullable(authenticator);
-    }
-
-    @Override
-    public ExecutorService executorService() {
-        return executor.userExecutor();
-    }
-
-    ExecutorWrapper executorWrapper() {
-        return executor;
-    }
-
-    @Override
-    public boolean pipelining() {
-        return this.pipelining;
-    }
-
-    ConnectionPool connectionPool() {
-        return connections;
-    }
-
-    @Override
-    public Redirect followRedirects() {
-        return followRedirects;
-    }
-
-
-    @Override
-    public Optional<CookieManager> cookieManager() {
-        return Optional.ofNullable(cookieManager);
-    }
-
-    @Override
-    public Optional<ProxySelector> proxy() {
-        return Optional.ofNullable(this.proxySelector);
-    }
-
-    @Override
-    public Version version() {
-        return version;
-    }
-
-    //private final HashMap<String, Boolean> http2NotSupported = new HashMap<>();
-
-    boolean getHttp2Allowed() {
-        return version.equals(Version.HTTP_2);
-    }
-
-    private void initFilters() {
-        addFilter(AuthenticationFilter.class);
-        addFilter(RedirectFilter.class);
-    }
-
-    private void addFilter(Class<? extends HeaderFilter> f) {
-        filters.addFilter(f);
-    }
-
-    final List<HeaderFilter> filterChain() {
-        return filters.getFilterChain();
-    }
-
-    // Timer controls. Timers are implemented through timed Selector.select()
-    // calls.
-    synchronized void registerTimer(TimeoutEvent event) {
-        long elapse = event.timevalMillis();
-        ListIterator<TimeoutEvent> iter = timeouts.listIterator();
-        long listval = 0;
-        event.delta = event.timeval; // in case list empty
-        TimeoutEvent next;
-        while (iter.hasNext()) {
-            next = iter.next();
-            listval += next.delta;
-            if (elapse < listval) {
-                listval -= next.delta;
-                event.delta = elapse - listval;
-                next.delta -= event.delta;
-                iter.previous();
-                break;
-            } else if (!iter.hasNext()) {
-                event.delta = event.timeval - listval;
-            }
-        }
-        iter.add(event);
-        selmgr.wakeupSelector();
-    }
-
-    private synchronized void signalTimeouts(long then) {
-        if (timeouts.isEmpty()) {
-            return;
-        }
-        long now = System.currentTimeMillis();
-        long duration = now - then;
-        ListIterator<TimeoutEvent> iter = timeouts.listIterator();
-        TimeoutEvent event = iter.next();
-        long delta = event.delta;
-        if (duration < delta) {
-            event.delta -= duration;
-            return;
-        }
-        event.handle();
-        iter.remove();
-        while (iter.hasNext()) {
-            event = iter.next();
-            if (event.delta == 0) {
-                event.handle();
-                iter.remove();
-            } else {
-                event.delta += delta;
-                break;
-            }
-        }
-    }
-
-    synchronized void cancelTimer(TimeoutEvent event) {
-        ListIterator<TimeoutEvent> iter = timeouts.listIterator();
-        while (iter.hasNext()) {
-            TimeoutEvent ev = iter.next();
-            if (event == ev) {
-                if (iter.hasNext()) {
-                    // adjust
-                    TimeoutEvent next = iter.next();
-                    next.delta += ev.delta;
-                    iter.previous();
-                }
-                iter.remove();
-            }
-        }
-    }
-
-    // used for the connection window
-    int getReceiveBufferSize() {
-        return Utils.getIntegerNetProperty(
-                "java.net.httpclient.connectionWindowSize", 256 * 1024
-        );
-    }
-
-    // returns 0 meaning block forever, or a number of millis to block for
-    private synchronized long getTimeoutValue() {
-        if (timeouts.isEmpty()) {
-            return 0;
-        } else {
-            return timeouts.get(0).delta;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.Closeable;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CompletableFuture;
-import javax.net.ssl.SSLParameters;
-
-/**
- * Wraps socket channel layer and takes care of SSL also.
- *
- * Subtypes are:
- *      PlainHttpConnection: regular direct TCP connection to server
- *      PlainProxyConnection: plain text proxy connection
- *      PlainTunnelingConnection: opens plain text (CONNECT) tunnel to server
- *      SSLConnection: TLS channel direct to server
- *      SSLTunnelConnection: TLS channel via (CONNECT) proxy tunnel
- */
-abstract class HttpConnection implements BufferHandler, Closeable {
-
-    protected final static ByteBuffer emptyBuf = Utils.EMPTY_BYTEBUFFER;
-
-    enum Mode {
-        BLOCKING,
-        NON_BLOCKING,
-        ASYNC
-    }
-
-    protected Mode mode;
-
-    // address we are connected to. Could be a server or a proxy
-    final InetSocketAddress address;
-    final HttpClientImpl client;
-    protected volatile ByteBuffer buffer;
-
-    HttpConnection(InetSocketAddress address, HttpClientImpl client) {
-        this.address = address;
-        this.client = client;
-        this.buffer = emptyBuf;
-    }
-
-    /**
-     * Public API to this class. addr is the ultimate destination. Any proxies
-     * etc are figured out from the request. Returns an instance of one of the
-     * following
-     *      PlainHttpConnection
-     *      PlainTunnelingConnection
-     *      SSLConnection
-     *      SSLTunnelConnection
-     *
-     * When object returned, connect() or connectAsync() must be called, which
-     * when it returns/completes, the connection is usable for requests.
-     */
-    public static HttpConnection getConnection(InetSocketAddress addr,
-                                               HttpRequestImpl request) {
-        return getConnectionImpl(addr, request, null);
-    }
-
-    /**
-     * Called specifically to get an async connection for HTTP/2 over SSL.
-     *
-     * @param addr
-     * @param request
-     * @param http2
-     * @return
-     */
-    public static HttpConnection getConnection(InetSocketAddress addr,
-        HttpRequestImpl request, Http2Connection http2) {
-
-        return getConnectionImpl(addr, request, http2);
-    }
-
-    public abstract void connect() throws IOException, InterruptedException;
-
-    public abstract CompletableFuture<Void> connectAsync();
-
-    /**
-     * Returns whether this connection is connected to its destination
-     */
-    abstract boolean connected();
-
-    abstract boolean isSecure();
-
-    abstract boolean isProxied();
-
-    /**
-     * Completes when the first byte of the response is available to be read.
-     */
-    abstract CompletableFuture<Void> whenReceivingResponse();
-
-    // must be called before reading any data off connection
-    // at beginning of response.
-    ByteBuffer getRemaining() {
-        ByteBuffer b = buffer;
-        buffer = emptyBuf;
-        return b;
-    }
-
-    final boolean isOpen() {
-        return channel().isOpen();
-    }
-
-    /* Returns either a plain HTTP connection or a plain tunnelling connection
-     * for proxied websockets */
-    private static HttpConnection getPlainConnection(InetSocketAddress addr,
-                                                     InetSocketAddress proxy,
-                                                     HttpRequestImpl request) {
-        HttpClientImpl client = request.client();
-
-        if (request.isWebSocket() && proxy != null) {
-            return new PlainTunnelingConnection(addr,
-                                                proxy,
-                                                client,
-                                                request.getAccessControlContext());
-        } else {
-            if (proxy == null) {
-                return new PlainHttpConnection(addr, client);
-            } else {
-                return new PlainProxyConnection(proxy, client);
-            }
-        }
-    }
-
-    private static HttpConnection getSSLConnection(InetSocketAddress addr,
-            InetSocketAddress proxy, HttpRequestImpl request,
-            String[] alpn, Http2Connection http2) {
-        HttpClientImpl client = request.client();
-        if (proxy != null) {
-            return new SSLTunnelConnection(addr,
-                                           client,
-                                           proxy,
-                                           request.getAccessControlContext());
-        } else if (http2 == null) {
-            return new SSLConnection(addr, client, alpn);
-        } else {
-            return new AsyncSSLConnection(addr, client, alpn);
-        }
-    }
-
-    /**
-     * Main factory method.   Gets a HttpConnection, either cached or new if
-     * none available.
-     */
-    private static HttpConnection getConnectionImpl(InetSocketAddress addr,
-            HttpRequestImpl request, Http2Connection http2) {
-
-        HttpConnection c;
-        HttpClientImpl client = request.client();
-        InetSocketAddress proxy = request.proxy();
-        boolean secure = request.secure();
-        ConnectionPool pool = client.connectionPool();
-        String[] alpn =  null;
-
-        if (secure && request.requestHttp2()) {
-            alpn = new String[1];
-            alpn[0] = "h2";
-        }
-
-        if (!secure) {
-            c = pool.getConnection(false, addr, proxy);
-            if (c != null) {
-                return c;
-            } else {
-                return getPlainConnection(addr, proxy, request);
-            }
-        } else {
-            c = pool.getConnection(true, addr, proxy);
-            if (c != null) {
-                return c;
-            } else {
-                return getSSLConnection(addr, proxy, request, alpn, http2);
-            }
-        }
-    }
-
-    void returnToCache(HttpHeaders hdrs) {
-        if (hdrs == null) {
-            // the connection was closed by server
-            close();
-            return;
-        }
-        if (!isOpen()) {
-            return;
-        }
-        ConnectionPool pool = client.connectionPool();
-        boolean keepAlive = hdrs.firstValue("Connection")
-                .map((s) -> !s.equalsIgnoreCase("close"))
-                .orElse(true);
-
-        if (keepAlive) {
-            pool.returnToPool(this);
-        } else {
-            close();
-        }
-    }
-
-    /**
-     * Also check that the number of bytes written is what was expected. This
-     * could be different if the buffer is user-supplied and its internal
-     * pointers were manipulated in a race condition.
-     */
-    final void checkWrite(long expected, ByteBuffer buffer) throws IOException {
-        long written = write(buffer);
-        if (written != expected) {
-            throw new IOException("incorrect number of bytes written");
-        }
-    }
-
-    final void checkWrite(long expected,
-                          ByteBuffer[] buffers,
-                          int start,
-                          int length)
-        throws IOException
-    {
-        long written = write(buffers, start, length);
-        if (written != expected) {
-            throw new IOException("incorrect number of bytes written");
-        }
-    }
-
-    abstract SocketChannel channel();
-
-    final InetSocketAddress address() {
-        return address;
-    }
-
-    synchronized void configureMode(Mode mode) throws IOException {
-        this.mode = mode;
-        if (mode == Mode.BLOCKING)
-            channel().configureBlocking(true);
-        else
-            channel().configureBlocking(false);
-    }
-
-    abstract ConnectionPool.CacheKey cacheKey();
-
-    // overridden in SSL only
-    SSLParameters sslParameters() {
-        return null;
-    }
-
-    // Methods to be implemented for Plain TCP and SSL
-
-    abstract long write(ByteBuffer[] buffers, int start, int number)
-        throws IOException;
-
-    abstract long write(ByteBuffer buffer) throws IOException;
-
-    /**
-     * Closes this connection, by returning the socket to its connection pool.
-     */
-    @Override
-    public abstract void close();
-
-    /**
-     * Returns a ByteBuffer with data, or null if EOF.
-     */
-    final ByteBuffer read() throws IOException {
-        return read(-1);
-    }
-
-    /**
-     * Puts position to limit and limit to capacity so we can resume reading
-     * into this buffer, but if required > 0 then limit may be reduced so that
-     * no more than required bytes are read next time.
-     */
-    static void resumeChannelRead(ByteBuffer buf, int required) {
-        int limit = buf.limit();
-        buf.position(limit);
-        int capacity = buf.capacity() - limit;
-        if (required > 0 && required < capacity) {
-            buf.limit(limit + required);
-        } else {
-            buf.limit(buf.capacity());
-        }
-    }
-
-    /**
-     * Blocks ands return requested amount.
-     */
-    final ByteBuffer read(int length) throws IOException {
-        if (length <= 0) {
-            buffer = readImpl(length);
-            return buffer;
-        }
-        buffer = readImpl(length);
-        int required = length - buffer.remaining();
-        while (buffer.remaining() < length) {
-            resumeChannelRead(buffer, required);
-            int n = readImpl(buffer);
-            required -= n;
-        }
-        return buffer;
-    }
-
-    final int read(ByteBuffer buffer) throws IOException {
-        int n = readImpl(buffer);
-        return n;
-    }
-
-    /** Reads up to length bytes. */
-    protected abstract ByteBuffer readImpl(int length) throws IOException;
-
-    /** Reads as much as possible into given buffer and returns amount read. */
-    protected abstract int readImpl(ByteBuffer buffer) throws IOException;
-
-    @Override
-    public String toString() {
-        return "HttpConnection: " + channel().toString();
-    }
-
-    @Override
-    public final ByteBuffer getBuffer(int n) {
-        return client.getBuffer(n);
-    }
-
-    @Override
-    public final void returnBuffer(ByteBuffer buffer) {
-        client.returnBuffer(buffer);
-    }
-
-    @Override
-    public final void setMinBufferSize(int n) {
-        client.setMinBufferSize(n);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpHeaders.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * A read-only view of a set of received HTTP headers.
- *
- * @since 9
- */
-public interface HttpHeaders {
-
-    /**
-     * Returns an {@link java.util.Optional} containing the first value of the
-     * given named (and possibly multi-valued) header. If the header is not
-     * present, then the returned {@code Optional} is empty.
-     *
-     * @param name the header name
-     * @return an {@code Optional<String>} for the first named value
-     */
-    public Optional<String> firstValue(String name);
-
-    /**
-     * Returns an {@link java.util.Optional} containing the first value of the
-     * named header field as an {@literal Optional<Long>}. If the header is not
-     * present, then the Optional is empty. If the header is present but
-     * contains a value that does not parse as a {@code Long} value, then an
-     * exception is thrown.
-     *
-     * @param name the header name
-     * @return  an {@code Optional<Long>}
-     * @throws NumberFormatException if a value is found, but does not parse as
-     *                               a Long
-     */
-    public Optional<Long> firstValueAsLong(String name);
-
-    /**
-     * Returns an unmodifiable List of all of the values of the given named
-     * header. Always returns a List, which may be empty if the header is not
-     * present.
-     *
-     * @param name the header name
-     * @return a List of String values
-     */
-    public List<String> allValues(String name);
-
-    /**
-     * Returns an unmodifiable multi Map view of this HttpHeaders. This
-     * interface should only be used when it is required to iterate over the
-     * entire set of headers.
-     *
-     * @return the Map
-     */
-    public Map<String,List<String>> map();
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpHeadersImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeMap;
-
-/**
- * Implementation of HttpHeaders.
- */
-class HttpHeadersImpl implements HttpHeaders {
-
-    private final TreeMap<String,List<String>> headers;
-
-    public HttpHeadersImpl() {
-        headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-    }
-
-    @Override
-    public Optional<String> firstValue(String name) {
-        List<String> l = headers.get(name);
-        return Optional.ofNullable(l == null ? null : l.get(0));
-    }
-
-    @Override
-    public List<String> allValues(String name) {
-        return headers.get(name);
-    }
-
-    @Override
-    public Map<String, List<String>> map() {
-        return Collections.unmodifiableMap(headers);
-    }
-
-    Map<String, List<String>> directMap() {
-        return headers;
-    }
-
-    // package private mutators
-
-    public HttpHeadersImpl deepCopy() {
-        HttpHeadersImpl h1 = new HttpHeadersImpl();
-        TreeMap<String,List<String>> headers1 = h1.headers;
-        Set<String> keys = headers.keySet();
-        for (String key : keys) {
-            List<String> vals = headers.get(key);
-            LinkedList<String> vals1 = new LinkedList<>(vals);
-            headers1.put(key, vals1);
-        }
-        return h1;
-    }
-
-    void addHeader(String name, String value) {
-        headers.computeIfAbsent(name, k -> new LinkedList<>())
-               .add(value);
-    }
-
-    void setHeader(String name, String value) {
-        List<String> l = headers.computeIfAbsent(name, k -> new LinkedList<>());
-        l.clear();
-        l.add(value);
-    }
-
-    @Override
-    public Optional<Long> firstValueAsLong(String name) {
-        List<String> l = headers.get(name);
-        if (l == null) {
-            return Optional.empty();
-        } else {
-            String v = l.get(0);
-            Long lv = Long.parseLong(v);
-            return Optional.of(lv);
-        }
-    }
-
-    void clear() {
-        headers.clear();
-    }
-}
\ No newline at end of file
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpRedirectImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.*;
-
-interface HttpRedirectImpl {
-
-    static HttpRedirectImpl getRedirects(java.net.http.HttpClient.Redirect redir) {
-        switch (redir) {
-            case NEVER:
-                return HttpRedirectImpl.NEVER;
-            case ALWAYS:
-                return HttpRedirectImpl.ALWAYS;
-            case SECURE:
-                return HttpRedirectImpl.SECURE;
-            case SAME_PROTOCOL:
-                return HttpRedirectImpl.SAME_PROTOCOL;
-        }
-        return HttpRedirectImpl.NEVER;
-    }
-
-    static HttpClient.Redirect getRedirects(HttpRedirectImpl redir) {
-        if (redir == HttpRedirectImpl.NEVER) {
-            return HttpClient.Redirect.NEVER;
-        } else if (redir == HttpRedirectImpl.ALWAYS) {
-            return HttpClient.Redirect.ALWAYS;
-        } else if (redir == HttpRedirectImpl.SECURE) {
-            return HttpClient.Redirect.SECURE;
-        } else {
-            return HttpClient.Redirect.SAME_PROTOCOL;
-        }
-    }
-
-    /**
-     * Called to determine whether the given intermediate response
-     * with a redirection response code should be redirected. The target URI
-     * can be obtained from the "Location" header in the given response object.
-     *
-     * @param rsp the response from the redirected resource
-     * @return {@code true} if the redirect should be attempted automatically
-     * or {@code false} if not.
-     */
-    boolean redirect(HttpResponse rsp);
-
-    /**
-     * Never redirect.
-     */
-    static HttpRedirectImpl NEVER = (HttpResponse rsp) -> false;
-
-    /**
-     * Always redirect.
-     */
-    static HttpRedirectImpl ALWAYS = (HttpResponse rsp) -> true;
-
-    /**
-     * Redirect to same protocol only. Redirection may occur from HTTP URLs to
-     * other THHP URLs and from HTTPS URLs to other HTTPS URLs.
-     */
-    static HttpRedirectImpl SAME_PROTOCOL = (HttpResponse rsp) -> {
-        String orig = rsp.request().uri().getScheme().toLowerCase();
-        String redirect = URI.create(
-                rsp.headers().firstValue("Location").orElse(""))
-                .getScheme().toLowerCase();
-        return orig.equals(redirect);
-    };
-
-    /**
-     * Redirect always except from HTTPS URLs to HTTP URLs.
-     */
-    static HttpRedirectImpl SECURE = (HttpResponse rsp) -> {
-        String orig = rsp.request().uri().getScheme().toLowerCase();
-        String redirect = URI.create(
-                rsp.headers().firstValue("Location").orElse(""))
-                .getScheme().toLowerCase();
-        if (orig.equals("https")) {
-            return redirect.equals("https");
-        }
-        return true;
-    };
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,871 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InputStream;
-import java.io.UncheckedIOException;
-import java.net.URI;
-import java.net.ProxySelector;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.*;
-import java.nio.file.Path;
-import java.util.Iterator;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.function.LongConsumer;
-
-/**
- * Represents one HTTP request which can be sent to a server. {@code
- * HttpRequest}s are built from {@code HttpRequest} {@link HttpRequest.Builder
- * builder}s. {@code HttpRequest} builders are obtained from a {@link HttpClient}
- * by calling {@link HttpClient#request(java.net.URI) HttpClient.request}, or
- * by calling {@link #create(java.net.URI) HttpRequest.create} which returns a
- * builder on the <a href="HttpClient.html#defaultclient">default</a> client.
- * A request's {@link java.net.URI}, headers and body can be set. Request bodies
- * are provided through a {@link BodyProcessor} object. Once all required
- * parameters have been set in the builder, one of the builder methods should be
- * called, which sets the request method and returns a {@code HttpRequest}.
- * These methods are {@link Builder#GET() GET}, {@link HttpRequest.Builder#POST()
- * POST} and {@link HttpRequest.Builder#PUT() PUT} which return a GET, POST or
- * PUT request respectively. Alternatively, {@link
- * HttpRequest.Builder#method(String) method} can be called to set an arbitrary
- * method type (and return a {@code HttpRequest}). Builders can also be copied
- * and modified multiple times in order to build multiple related requests that
- * differ in some parameters.
- *
- * <p> Two simple, example HTTP interactions are shown below:
- * <pre>
- * {@code
- *      // GET
- *      HttpResponse response = HttpRequest
- *          .create(new URI("http://www.foo.com"))
- *          .headers("Foo", "foovalue", "Bar", "barvalue")
- *          .GET()
- *          .response();
- *
- *      int statusCode = response.statusCode();
- *      String responseBody = response.body(asString());
- *
- *      // POST
- *      response = HttpRequest
- *          .create(new URI("http://www.foo.com"))
- *          .body(fromString("param1=foo,param2=bar"))
- *          .POST()
- *          .response();}
- * </pre>
- *
- * <p> The request is sent and the response obtained by calling one of the
- * following methods.
- * <ul><li>{@link #response() response} blocks until the entire request has been
- * sent and the response status code and headers have been received.</li>
- * <li>{@link #responseAsync() responseAsync} sends the request and receives the
- * response asynchronously. Returns immediately with a
- * {@link java.util.concurrent.CompletableFuture CompletableFuture}&lt;{@link
- * HttpResponse}&gt;.</li>
- * <li>{@link #multiResponseAsync(HttpResponse.MultiProcessor) multiResponseAsync}
- * sends the request asynchronously, expecting multiple responses. This
- * capability is of most relevance to HTTP/2 server push, but can be used for
- * single responses (HTTP/1.1 or HTTP/2) also.</li>
- * </ul>
- *
- * <p> Once a request has been sent, it is an error to try and send it again.
- *
- * <p> Once a {@code HttpResponse} is received, the headers and response code are
- * available. The body can then be received by calling one of the body methods
- * on {@code HttpResponse}.
- *
- * <p> See below for discussion of synchronous versus asynchronous usage.
- *
- * <p> <b>Request bodies</b>
- *
- * <p> Request bodies are sent using one of the request processor implementations
- * below provided in {@code HttpRequest}, or else a custom implementation can be
- * used.
- * <ul>
- * <li>{@link #fromByteArray(byte[]) } from byte array</li>
- * <li>{@link #fromByteArrays(java.util.Iterator) fromByteArrays(Iterator)}
- *      from an iterator of byte arrays</li>
- * <li>{@link #fromFile(java.nio.file.Path) fromFile(Path)} from the file located
- *     at the given Path</li>
- * <li>{@link #fromString(java.lang.String) fromString(String)} from a String </li>
- * <li>{@link #fromInputStream(java.io.InputStream) fromInputStream(InputStream)}
- *      request body from InputStream</li>
- * <li>{@link #noBody() } no request body is sent</li>
- * </ul>
- *
- * <p> <b>Response bodies</b>
- *
- * <p> Responses bodies are handled by the {@link HttpResponse.BodyProcessor}
- * {@code <T>} supplied to the {@link HttpResponse#body(HttpResponse.BodyProcessor)
- * HttpResponse.body} and {@link HttpResponse#bodyAsync(HttpResponse.BodyProcessor)
- * HttpResponse.bodyAsync} methods. Some implementations of {@code
- * HttpResponse.BodyProcessor} are provided in {@link HttpResponse}:
- * <ul>
- * <li>{@link HttpResponse#asByteArray() } stores the body in a byte array</li>
- * <li>{@link HttpResponse#asString()} stores the body as a String </li>
- * <li>{@link HttpResponse#asFile(java.nio.file.Path) } stores the body in a
- * named file</li>
- * <li>{@link HttpResponse#ignoreBody() } ignores any received response body</li>
- * </ul>
- *
- * <p> The output of a response processor is the response body, and its
- * parameterized type {@code T} determines the type of the body object returned
- * from {@code HttpResponse.body} and {@code HttpResponse.bodyAsync}. Therefore,
- * as an example, the second response processor in the list above has the type
- * {@code HttpResponse.BodyProcessor<String>} which means the type returned by
- * {@code HttpResponse.body()} is a String. Response processors can be defined
- * to return potentially any type as body.
- *
- * <p> <b>Multi responses</b>
- *
- * <p> With HTTP/2 it is possible for a server to return a main response and zero
- * or more additional responses (known as server pushes) to a client-initiated
- * request. These are handled using a special response processor called {@link
- * HttpResponse.MultiProcessor}.
- *
- * <p> <b>Blocking/asynchronous behavior and thread usage</b>
- *
- * <p> There are two styles of request sending: <i>synchronous</i> and
- * <i>asynchronous</i>. {@link #response() response} blocks the calling thread
- * until the request has been sent and the response received.
- *
- * <p> {@link #responseAsync() responseAsync} is asynchronous and returns
- * immediately with a {@link java.util.concurrent.CompletableFuture}&lt;{@link
- * HttpResponse}&gt; and when this object completes (in a background thread) the
- * response has been received.
- *
- * <p> {@link #multiResponseAsync(HttpResponse.MultiProcessor) multiResponseAsync}
- * is the variant for multi responses and is also asynchronous.
- *
- * <p> CompletableFutures can be combined in different ways to declare the
- * dependencies among several asynchronous tasks, while allowing for the maximum
- * level of parallelism to be utilized.
- *
- * <p> <b>Security checks</b>
- *
- * <p> If a security manager is present then security checks are performed by
- * the {@link #response() } and {@link #responseAsync() } methods. A {@link
- * java.net.URLPermission} or {@link java.net.SocketPermission} is required to
- * access any destination origin server and proxy server utilised. URLPermissions
- * should be preferred in policy files over SocketPermissions given the more
- * limited scope of URLPermission. Permission is always implicitly granted to a
- * system's default proxies. The URLPermission form used to access proxies uses
- * a method parameter of "CONNECT" (for all kinds of proxying) and a url string
- * of the form "socket://host:port" where host and port specify the proxy's
- * address.
- *
- * <p> <b>Examples</b>
- * <pre>
- *     import static java.net.http.HttpRequest.*;
- *     import static java.net.http.HttpResponse.*;
- *
- *     //Simple blocking
- *
- *     HttpResponse r1 = HttpRequest.create(new URI("http://www.foo.com/"))
- *                                  .GET()
- *                                 .response();
- *     int responseCode = r1.statusCode());
- *     String body = r1.body(asString());
- *
- *     HttpResponse r2 = HttpRequest.create(new URI("http://www.foo.com/"))
- *                                  .GET()
- *                                  .response();
- *
- *     System.out.println("Response was " + r1.statusCode());
- *     Path body1 = r2.body(asFile(Paths.get("/tmp/response.txt")));
- *     // Content stored in /tmp/response.txt
- *
- *     HttpResponse r3 = HttpRequest.create(new URI("http://www.foo.com/"))
- *                                  .body(fromString("param1=1, param2=2"))
- *                                  .POST()
- *                                  .response();
- *
- *     Void body2 = r3.body(ignoreBody()); // body is Void in this case
- * </pre>
- *
- * <p><b>Asynchronous Example</b>
- *
- * <p> All of the above examples will work asynchronously, if {@link
- * #responseAsync()} is used instead of {@link #response()} in which case the
- * returned object is a {@code CompletableFuture<HttpResponse>} instead of
- * {@code HttpResponse}. The following example shows how multiple requests can
- * be sent asynchronously. It also shows how dependent asynchronous operations
- * (receiving response, and receiving response body) can be chained easily using
- * one of the many methods in {@code CompletableFuture}.
- * <pre>
- * {@code
- *      // fetch a list of target URIs asynchronously and store them in Files.
- *
- *      List<URI> targets = ...
- *
- *      List<CompletableFuture<File>> futures = targets
- *          .stream()
- *          .map(target -> {
- *              return HttpRequest
- *                  .create(target)
- *                  .GET()
- *                  .responseAsync()
- *                  .thenCompose(response -> {
- *                      Path dest = Paths.get("base", target.getPath());
- *                      if (response.statusCode() == 200) {
- *                          return response.bodyAsync(asFile(dest));
- *                      } else {
- *                          return CompletableFuture.completedFuture(dest);
- *                      }
- *                  })
- *                  // convert Path -> File
- *                  .thenApply((Path dest) -> {
- *                      return dest.toFile();
- *                  });
- *              })
- *          .collect(Collectors.toList());
- *
- *      // all async operations waited for here
- *
- *      CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]))
- *          .join();
- *
- *      // all elements of futures have completed and can be examined.
- *      // Use File.exists() to check whether file was successfully downloaded
- * }
- * </pre>
- *
- * @since 9
- */
-public abstract class HttpRequest {
-
-    HttpRequest() {}
-
-    /**
-     * A builder of {@link HttpRequest}s. {@code HttpRequest.Builder}s are
-     * created by calling {@link HttpRequest#create(URI)} or {@link
-     * HttpClient#request(URI)}.
-     *
-     * <p> Each of the setter methods in this class modifies the state of the
-     * builder and returns <i>this</i> (ie. the same instance). The methods are
-     * not synchronized and should not be called from multiple threads without
-     * external synchronization.
-     *
-     * <p> The build methods return a new {@code HttpRequest} each time they are
-     * called.
-     *
-     * @since 9
-     */
-    public abstract static class Builder {
-
-        Builder() {}
-
-        /**
-         * Sets this HttpRequest's request URI.
-         *
-         * @param uri the request URI
-         * @return this request builder
-         */
-        public abstract Builder uri(URI uri);
-
-        /**
-         * Specifies whether this request will automatically follow redirects
-         * issued by the server. The default value for this setting is the value
-         * of {@link HttpClient#followRedirects() }
-         *
-         * @param policy the redirection policy
-         * @return this request builder
-         */
-        public abstract Builder followRedirects(HttpClient.Redirect policy);
-
-        /**
-         * Request server to acknowledge request before sending request
-         * body. This is disabled by default. If enabled, the server is requested
-         * to send an error response or a 100-Continue response before the client
-         * sends the request body. This means the request processor for the
-         * request will not be invoked until this interim response is received.
-         *
-         * @param enable {@code true} if Expect continue to be sent
-         * @return this request builder
-         */
-        public abstract Builder expectContinue(boolean enable);
-
-        /**
-         * Overrides the {@link HttpClient#version()  } setting for this
-         * request.
-         *
-         * @param version the HTTP protocol version requested
-         * @return this request builder
-         */
-        public abstract Builder version(HttpClient.Version version);
-
-        /**
-         * Adds the given name value pair to the set of headers for this request.
-         *
-         * @param name the header name
-         * @param value the header value
-         * @return this request builder
-         */
-        public abstract Builder header(String name, String value);
-
-        /**
-         * Overrides the ProxySelector set on the request's client for this
-         * request.
-         *
-         * @param proxy the ProxySelector to use
-         * @return this request builder
-         */
-        public abstract Builder proxy(ProxySelector proxy);
-
-        /**
-         * Adds the given name value pairs to the set of headers for this
-         * request. The supplied Strings must alternate as names and values.
-         *
-         * @param headers the list of String name value pairs
-         * @return this request builder
-         * @throws IllegalArgumentException if there is an odd number of
-         *                                  parameters
-         */
-        public abstract Builder headers(String... headers);
-
-        /**
-         * Sets a timeout for this request. If the response is not received
-         * within the specified timeout then a {@link HttpTimeoutException} is
-         * thrown from {@link #response() } or {@link #responseAsync() }
-         * completes exceptionally with a {@code HttpTimeoutException}.
-         *
-         * @param unit the timeout units
-         * @param timeval the number of units to wait for
-         * @return this request builder
-         */
-        public abstract Builder timeout(TimeUnit unit, long timeval);
-
-        /**
-         * Sets the given name value pair to the set of headers for this
-         * request. This overwrites any previously set values for name.
-         *
-         * @param name the header name
-         * @param value the header value
-         * @return this request builder
-         */
-        public abstract Builder setHeader(String name, String value);
-
-        /**
-         * Sets a request body for this builder. See {@link HttpRequest}
-         * for example {@code BodyProcessor} implementations.
-         * If no body is specified, then no body is sent with the request.
-         *
-         * @param reqproc the request body processor
-         * @return this request builder
-         */
-        public abstract Builder body(BodyProcessor reqproc);
-
-        /**
-         * Builds and returns a GET {@link HttpRequest} from this builder.
-         *
-         * @return a {@code HttpRequest}
-         */
-        public abstract HttpRequest GET();
-
-        /**
-         * Builds and returns a POST {@link HttpRequest} from this builder.
-         *
-         * @return a {@code HttpRequest}
-         */
-        public abstract HttpRequest POST();
-
-        /**
-         * Builds and returns a PUT {@link HttpRequest} from this builder.
-         *
-         * @return a {@code HttpRequest}
-         */
-        public abstract HttpRequest PUT();
-
-        /**
-         * Builds and returns a {@link HttpRequest} from this builder using
-         * the given method String. The method string is case-sensitive, and
-         * may be rejected if an upper-case string is not used.
-         *
-         * @param method the method to use
-         * @return a {@code HttpRequest}
-         * @throws IllegalArgumentException if an unrecognised method is used
-         */
-        public abstract HttpRequest method(String method);
-
-        /**
-         * Returns an exact duplicate copy of this Builder based on current
-         * state. The new builder can then be modified independently of this
-         * builder.
-         *
-         * @return an exact copy of this Builder
-         */
-        public abstract Builder copy();
-    }
-
-    /**
-     * Creates a HttpRequest builder from the <i>default</i> HttpClient.
-     *
-     * @param uri the request URI
-     * @return a new request builder
-     */
-    public static HttpRequest.Builder create(URI uri) {
-        return HttpClient.getDefault().request(uri);
-    }
-
-    /**
-     * Returns the follow-redirects setting for this request.
-     *
-     * @return follow redirects setting
-     */
-    public abstract HttpClient.Redirect followRedirects();
-
-    /**
-     * Returns the response to this request, by sending it and blocking if
-     * necessary to get the response. The {@link HttpResponse} contains the
-     * response status and headers.
-     *
-     * @return a HttpResponse for this request
-     * @throws IOException if an I/O error occurs
-     * @throws InterruptedException if the operation was interrupted
-     * @throws SecurityException if the caller does not have the required
-     *                           permission
-     * @throws IllegalStateException if called more than once or if
-     *                               responseAsync() called previously
-     */
-    public abstract HttpResponse response()
-        throws IOException, InterruptedException;
-
-    /**
-     * Sends the request and returns the response asynchronously. This method
-     * returns immediately with a {@link CompletableFuture}&lt;{@link
-     * HttpResponse}&gt;
-     *
-     * @return a {@code CompletableFuture<HttpResponse>}
-     * @throws IllegalStateException if called more than once or if response()
-     *                               called previously.
-     */
-    public abstract CompletableFuture<HttpResponse> responseAsync();
-
-    /**
-     * Sends the request asynchronously expecting multiple responses.
-     *
-     * <p> This method must be given a {@link HttpResponse.MultiProcessor} to
-     * handle the multiple responses.
-     *
-     * <p> If a security manager is set, the caller must possess a {@link
-     * java.net.URLPermission} for the request's URI, method and any user set
-     * headers. The security manager is also checked for each incoming
-     * additional server generated request/response. Any request that fails the
-     * security check, is canceled and ignored.
-     *
-     * <p> This method can be used for both HTTP/1.1 and HTTP/2, but in cases
-     * where multiple responses are not supported, the MultiProcessor
-     * only receives the main response.
-     *
-     * <p> The aggregate {@code CompletableFuture} returned from this method
-     * returns a {@code <U>} defined by the {@link HttpResponse.MultiProcessor}
-     * implementation supplied. This will typically be a Collection of
-     * HttpResponses or of some response body type.
-     *
-     * @param <U> the aggregate response type
-     * @param rspproc the MultiProcessor for the request
-     * @return a {@code CompletableFuture<U>}
-     * @throws IllegalStateException if the request has already been sent.
-     */
-    public abstract <U> CompletableFuture<U>
-    multiResponseAsync(HttpResponse.MultiProcessor<U> rspproc);
-
-    /**
-     * Returns the request method for this request. If not set explicitly,
-     * the default method for any request is "GET".
-     *
-     * @return this request's method
-     */
-    public abstract String method();
-
-    /**
-     * Returns this request's {@link HttpRequest.Builder#expectContinue(boolean)
-     * expect continue } setting.
-     *
-     * @return this request's expect continue setting
-     */
-    public abstract boolean expectContinue();
-
-    /**
-     * Returns this request's request URI.
-     *
-     * @return this request's URI
-     */
-    public abstract URI uri();
-
-    /**
-     * Returns this request's {@link HttpClient}.
-     *
-     * @return this request's HttpClient
-     */
-    public abstract HttpClient client();
-
-    /**
-     * Returns the HTTP protocol version that this request will use or used.
-     *
-     * @return HTTP protocol version
-     */
-    public abstract HttpClient.Version version();
-
-    /**
-     * The (user-accessible) request headers that this request was (or will be)
-     * sent with.
-     *
-     * @return this request's HttpHeaders
-     */
-    public abstract HttpHeaders headers();
-
-    /**
-     * Returns a request processor whose body is the given String, converted
-     * using the {@link java.nio.charset.StandardCharsets#ISO_8859_1 ISO_8859_1}
-     * character set.
-     *
-     * @param body the String containing the body
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromString(String body) {
-        return fromString(body, StandardCharsets.ISO_8859_1);
-    }
-
-    /**
-     * A request processor that takes data from the contents of a File.
-     *
-     * @param path the path to the file containing the body
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromFile(Path path) {
-        FileChannel fc;
-        long size;
-
-        try {
-            fc = FileChannel.open(path);
-            size = fc.size();
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-
-        return new BodyProcessor() {
-            LongConsumer flow;
-
-            @Override
-            public long onRequestStart(HttpRequest hr, LongConsumer flow) {
-                // could return exact file length, but for now -1
-                this.flow = flow;
-                flow.accept(1);
-                if (size != 0) {
-                    return size;
-                } else {
-                    return -1;
-                }
-            }
-
-            @Override
-            public boolean onRequestBodyChunk(ByteBuffer buffer) throws IOException {
-                int n = fc.read(buffer);
-                if (n == -1) {
-                    fc.close();
-                    return true;
-                }
-                flow.accept(1);
-                return false;
-            }
-
-            @Override
-            public void onRequestError(Throwable t) {
-                try {
-                    fc.close();
-                } catch (IOException ex) {
-                    Log.logError(ex.toString());
-                }
-            }
-        };
-    }
-
-    /**
-     * Returns a request processor whose body is the given String, converted
-     * using the given character set.
-     *
-     * @param s the String containing the body
-     * @param charset the character set to convert the string to bytes
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromString(String s, Charset charset) {
-        return fromByteArray(s.getBytes(charset));
-    }
-
-    /**
-     * Returns a request processor whose body is the given byte array.
-     *
-     * @param buf the byte array containing the body
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromByteArray(byte[] buf) {
-        return fromByteArray(buf, 0, buf.length);
-    }
-
-    /**
-     * Returns a request processor whose body is the content of the given byte
-     * array length bytes starting from the specified offset.
-     *
-     * @param buf the byte array containing the body
-     * @param offset the offset of the first byte
-     * @param length the number of bytes to use
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromByteArray(byte[] buf, int offset, int length) {
-
-        return new BodyProcessor() {
-            LongConsumer flow;
-            byte[] barray;
-            int index;
-            int sent;
-
-            @Override
-            public long onRequestStart(HttpRequest hr, LongConsumer flow) {
-                this.flow = flow;
-                flow.accept(1);
-                barray = buf;
-                index = offset;
-                return length;
-            }
-
-            @Override
-            public boolean onRequestBodyChunk(ByteBuffer buffer)
-                throws IOException
-            {
-                if (sent == length) {
-                    return true;
-                }
-
-                int remaining = buffer.remaining();
-                int left = length - sent;
-                int n = remaining > left ? left : remaining;
-                buffer.put(barray, index, n);
-                index += n;
-                sent += n;
-                flow.accept(1);
-                return sent == length;
-            }
-
-            @Override
-            public void onRequestError(Throwable t) {
-                Log.logError(t.toString());
-            }
-        };
-    }
-
-    /**
-     * A request processor that takes data from an Iterator of byte arrays.
-     *
-     * @param iter an Iterator of byte arrays
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromByteArrays(Iterator<byte[]> iter) {
-
-        return new BodyProcessor() {
-            LongConsumer flow;
-            byte[] current;
-            int curIndex;
-
-            @Override
-            public long onRequestStart(HttpRequest hr, LongConsumer flow) {
-                this.flow = flow;
-                flow.accept(1);
-                return -1;
-            }
-
-            @Override
-            public boolean onRequestBodyChunk(ByteBuffer buffer)
-                throws IOException
-            {
-                int remaining;
-
-                while ((remaining = buffer.remaining()) > 0) {
-                    if (current == null) {
-                        if (!iter.hasNext()) {
-                            return true;
-                        }
-                        current = iter.next();
-                        curIndex = 0;
-                    }
-                    int n = Math.min(remaining, current.length - curIndex);
-                    buffer.put(current, curIndex, n);
-                    curIndex += n;
-
-                    if (curIndex == current.length) {
-                        current = null;
-                        flow.accept(1);
-                        return false;
-                    }
-                }
-                flow.accept(1);
-                return false;
-            }
-
-            @Override
-            public void onRequestError(Throwable t) {
-                Log.logError(t.toString());
-            }
-        };
-    }
-
-    /**
-     * A request processor that reads its data from an InputStream.
-     *
-     * @param stream an InputStream
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor fromInputStream(InputStream stream) {
-        // for now, this blocks. It could be offloaded to a separate thread
-        // to do reading and guarantee that onRequestBodyChunk() won't block
-        return new BodyProcessor() {
-            LongConsumer flow;
-
-            @Override
-            public long onRequestStart(HttpRequest hr, LongConsumer flow) {
-                this.flow = flow;
-                flow.accept(1);
-                return -1;
-            }
-
-            @Override
-            public boolean onRequestBodyChunk(ByteBuffer buffer)
-                throws IOException
-            {
-                int remaining = buffer.remaining();
-                int n = stream.read(buffer.array(), buffer.arrayOffset(), remaining);
-                if (n == -1) {
-                    stream.close();
-                    return true;
-                }
-                buffer.position(buffer.position() + n);
-                flow.accept(1);
-                return false;
-            }
-
-            @Override
-            public void onRequestError(Throwable t) {
-                Log.logError(t.toString());
-            }
-        };
-    }
-
-    /**
-     * A request processor which sends no request body.
-     *
-     * @return a BodyProcessor
-     */
-    public static BodyProcessor noBody() {
-        return new BodyProcessor() {
-
-            @Override
-            public long onRequestStart(HttpRequest hr, LongConsumer flow) {
-                return 0;
-            }
-
-            @Override
-            public boolean onRequestBodyChunk(ByteBuffer buffer)
-                throws IOException
-            {
-                throw new InternalError("should never reach here");
-            }
-
-            @Override
-            public void onRequestError(Throwable t) {
-                Log.logError(t.toString());
-            }
-        };
-    }
-
-    /**
-     * A request processor which obtains the request body from some source.
-     * Implementations of this interface are provided which allow request bodies
-     * to be supplied from standard types, such as {@code String, byte[], File,
-     * InputStream}. Other implementations can be provided.
-     *
-     * <p> The methods of this interface may be called from multiple threads,
-     * but only one method is invoked at a time, and behaves as if called from
-     * one thread.
-     *
-     * <p> See {@link HttpRequest} for implementations that take request bodies
-     * from {@code byte arrays, Strings, Paths} etc.
-     *
-     * @since 9
-     */
-    public interface BodyProcessor {
-
-        /**
-         * Called before a request is sent. Is expected to return the content
-         * length of the request body. Zero means no content. Less than zero
-         * means an unknown positive content-length, and the body will be
-         * streamed.
-         *
-         * <p> The flowController object must be used to manage the flow of
-         * calls to {@link #onRequestBodyChunk(ByteBuffer)}. The typical usage
-         * for a non-blocking processor is to call it once inside
-         * onRequestStart() and once during each call to onRequestBodyChunk().
-         *
-         * @param hr the request
-         * @param flowController the HttpFlowController
-         * @return the content length
-         * @throws IOException if an I/O error occurs
-         */
-        long onRequestStart(HttpRequest hr, LongConsumer flowController)
-            throws IOException;
-
-        /**
-         * Called if sending a request body fails.
-         *
-         * @implSpec The default implementation does nothing.
-         *
-         * @param t the Throwable that caused the failure
-         */
-        default void onRequestError(Throwable t) { }
-
-        /**
-         * Called to obtain a buffer of data to send. The data must be placed
-         * in the provided buffer. The implementation should not block. The
-         * boolean return code notifies the protocol implementation if the
-         * supplied buffer is the final one (or not).
-         *
-         * @param buffer a ByteBuffer to write data into
-         * @return whether or not this is the last buffer
-         * @throws IOException if an I/O error occurs
-         */
-        boolean onRequestBodyChunk(ByteBuffer buffer) throws IOException;
-
-        /**
-         * Called when the request body has been completely sent.
-         *
-         * @implSpec The default implementation does nothing
-         */
-        default void onComplete() {
-            // TODO: need to call this
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestBuilderImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.ProxySelector;
-import java.util.Objects;
-import java.util.concurrent.TimeUnit;
-
-class HttpRequestBuilderImpl extends HttpRequest.Builder {
-
-    private HttpHeadersImpl userHeaders;
-    private URI uri;
-    private String method;
-    private HttpClient.Redirect followRedirects;
-    private boolean expectContinue;
-    private HttpRequest.BodyProcessor body;
-    private HttpClient.Version version;
-    private final HttpClientImpl client;
-    private ProxySelector proxy;
-    private long timeval;
-
-    public HttpRequestBuilderImpl(HttpClientImpl client, URI uri) {
-        this.client = client;
-        checkURI(uri);
-        this.uri = uri;
-        this.version = client.version();
-        this.userHeaders = new HttpHeadersImpl();
-    }
-
-    @Override
-    public HttpRequestBuilderImpl body(HttpRequest.BodyProcessor reqproc) {
-        Objects.requireNonNull(reqproc);
-        this.body = reqproc;
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl uri(URI uri) {
-        Objects.requireNonNull(uri);
-        checkURI(uri);
-        this.uri = uri;
-        return this;
-    }
-
-    private static void checkURI(URI uri) {
-        String scheme = uri.getScheme().toLowerCase();
-        if (!scheme.equals("https") && !scheme.equals("http"))
-            throw new IllegalArgumentException("invalid URI scheme");
-    }
-
-    @Override
-    public HttpRequestBuilderImpl followRedirects(HttpClient.Redirect follow) {
-        Objects.requireNonNull(follow);
-        this.followRedirects = follow;
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl header(String name, String value) {
-        Objects.requireNonNull(name);
-        Objects.requireNonNull(value);
-        Utils.validateToken(name, "invalid header name");
-        userHeaders.addHeader(name, value);
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl headers(String... params) {
-        Objects.requireNonNull(params);
-        if (params.length % 2 != 0) {
-            throw new IllegalArgumentException("wrong number of parameters");
-        }
-        for (int i=0; i<params.length; ) {
-            String name = params[i];
-            String value = params[i+1];
-            header(name, value);
-            i+=2;
-        }
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl proxy(ProxySelector proxy) {
-        Objects.requireNonNull(proxy);
-        this.proxy = proxy;
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl copy() {
-        HttpRequestBuilderImpl b = new HttpRequestBuilderImpl(this.client, this.uri);
-        b.userHeaders = this.userHeaders.deepCopy();
-        b.method = this.method;
-        b.followRedirects = this.followRedirects;
-        b.expectContinue = this.expectContinue;
-        b.body = body;
-        b.uri = uri;
-        b.proxy = proxy;
-        return b;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl setHeader(String name, String value) {
-        Objects.requireNonNull(name);
-        Objects.requireNonNull(value);
-        userHeaders.setHeader(name, value);
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl expectContinue(boolean enable) {
-        expectContinue = enable;
-        return this;
-    }
-
-    @Override
-    public HttpRequestBuilderImpl version(HttpClient.Version version) {
-        Objects.requireNonNull(version);
-        this.version = version;
-        return this;
-    }
-
-    HttpHeadersImpl headers() {  return userHeaders; }
-
-    URI uri() { return uri; }
-
-    String method() { return method; }
-
-    HttpClient.Redirect followRedirects() { return followRedirects; }
-
-    ProxySelector proxy() { return proxy; }
-
-    boolean expectContinue() { return expectContinue; }
-
-    HttpRequest.BodyProcessor body() { return body; }
-
-    HttpClient.Version version() { return version; }
-
-    @Override
-    public HttpRequest GET() { return method("GET"); }
-
-    @Override
-    public HttpRequest POST() { return method("POST"); }
-
-    @Override
-    public HttpRequest PUT() { return method("PUT"); }
-
-    @Override
-    public HttpRequest method(String method) {
-        Objects.requireNonNull(method);
-        this.method = method;
-        return new HttpRequestImpl(client, method, this);
-    }
-
-    @Override
-    public HttpRequest.Builder timeout(TimeUnit timeunit, long timeval) {
-        Objects.requireNonNull(timeunit);
-        this.timeval = timeunit.toMillis(timeval);
-        return this;
-    }
-
-    long timeval() { return timeval; }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.net.ProxySelector;
-import java.net.URI;
-import java.net.http.HttpClient.Version;
-import java.net.http.HttpResponse.MultiProcessor;
-import java.util.concurrent.CompletableFuture;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import static java.net.http.HttpRedirectImpl.getRedirects;
-import java.util.Locale;
-
-class HttpRequestImpl extends HttpRequest {
-
-    private final ImmutableHeaders userHeaders;
-    private final HttpHeadersImpl systemHeaders;
-    private final URI uri;
-    private InetSocketAddress authority; // only used when URI not specified
-    private final String method;
-    private final HttpClientImpl client;
-    private final HttpRedirectImpl followRedirects;
-    private final ProxySelector proxy;
-    final BodyProcessor requestProcessor;
-    final boolean secure;
-    final boolean expectContinue;
-    private final java.net.http.HttpClient.Version version;
-    private boolean isWebSocket;
-    final MultiExchange exchange;
-    private boolean receiving;
-    private AccessControlContext acc;
-    private final long timeval;
-    private Stream.PushGroup<?> pushGroup;
-
-    public HttpRequestImpl(HttpClientImpl client,
-                           String method,
-                           HttpRequestBuilderImpl builder) {
-        this.client = client;
-        this.method = method == null? "GET" : method;
-        this.userHeaders = builder.headers() == null ?
-                new ImmutableHeaders() :
-                new ImmutableHeaders(builder.headers(), Utils.ALLOWED_HEADERS);
-        this.followRedirects = getRedirects(builder.followRedirects() == null ?
-                client.followRedirects() : builder.followRedirects());
-        this.systemHeaders = new HttpHeadersImpl();
-        this.uri = builder.uri();
-        this.proxy = builder.proxy();
-        this.expectContinue = builder.expectContinue();
-        this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
-        this.version = builder.version();
-        if (builder.body() == null) {
-            this.requestProcessor = HttpRequest.noBody();
-        } else {
-            this.requestProcessor = builder.body();
-        }
-        this.exchange = new MultiExchange(this);
-        this.timeval = builder.timeval();
-    }
-
-    /** Creates a HttpRequestImpl using fields of an existing request impl. */
-    public HttpRequestImpl(URI uri,
-                           HttpRequest request,
-                           HttpClientImpl client,
-                           String method,
-                           HttpRequestImpl other) {
-        this.client = client;
-        this.method = method == null? "GET" : method;
-        this.userHeaders = other.userHeaders;
-        this.followRedirects = getRedirects(other.followRedirects() == null ?
-                client.followRedirects() : other.followRedirects());
-        this.systemHeaders = other.systemHeaders;
-        this.uri = uri;
-        this.expectContinue = other.expectContinue;
-        this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
-        this.requestProcessor = other.requestProcessor;
-        this.proxy = other.proxy;
-        this.version = other.version;
-        this.acc = other.acc;
-        this.exchange = new MultiExchange(this);
-        this.timeval = other.timeval;
-    }
-
-    /* used for creating CONNECT requests  */
-    HttpRequestImpl(HttpClientImpl client,
-                    String method,
-                    InetSocketAddress authority) {
-        this.client = client;
-        this.method = method;
-        this.followRedirects = getRedirects(client.followRedirects());
-        this.systemHeaders = new HttpHeadersImpl();
-        this.userHeaders = new ImmutableHeaders();
-        this.uri = null;
-        this.proxy = null;
-        this.requestProcessor = HttpRequest.noBody();
-        this.version = java.net.http.HttpClient.Version.HTTP_1_1;
-        this.authority = authority;
-        this.secure = false;
-        this.expectContinue = false;
-        this.exchange = new MultiExchange(this);
-        this.timeval = 0; // block TODO: fix
-    }
-
-    @Override
-    public HttpClientImpl client() {
-        return client;
-    }
-
-    /**
-     * Creates a HttpRequestImpl from the given set of Headers and the associated
-     * "parent" request. Fields not taken from the headers are taken from the
-     * parent.
-     */
-    static HttpRequestImpl createPushRequest(HttpRequestImpl parent,
-            HttpHeadersImpl headers) throws IOException {
-
-        return new HttpRequestImpl(parent, headers);
-    }
-
-    // only used for push requests
-    private HttpRequestImpl(HttpRequestImpl parent, HttpHeadersImpl headers) throws IOException {
-        this.method = headers.firstValue(":method")
-                .orElseThrow(() -> new IOException("No method in Push Promise"));
-        String path = headers.firstValue(":path")
-                .orElseThrow(() -> new IOException("No path in Push Promise"));
-        String scheme = headers.firstValue(":scheme")
-                .orElseThrow(() -> new IOException("No scheme in Push Promise"));
-        String authority = headers.firstValue(":authority")
-                .orElseThrow(() -> new IOException("No authority in Push Promise"));
-        StringBuilder sb = new StringBuilder();
-        sb.append(scheme).append("://").append(authority).append(path);
-        this.uri = URI.create(sb.toString());
-
-        this.client = parent.client;
-        this.userHeaders = new ImmutableHeaders(headers, Utils.ALLOWED_HEADERS);
-        this.followRedirects = parent.followRedirects;
-        this.systemHeaders = parent.systemHeaders;
-        this.expectContinue = parent.expectContinue;
-        this.secure = parent.secure;
-        this.requestProcessor = parent.requestProcessor;
-        this.proxy = parent.proxy;
-        this.version = parent.version;
-        this.acc = parent.acc;
-        this.exchange = parent.exchange;
-        this.timeval = parent.timeval;
-    }
-
-    @Override
-    public String toString() {
-        return (uri == null ? "" : uri.toString()) + " " + method;
-    }
-
-    @Override
-    public HttpHeaders headers() {
-        return userHeaders;
-    }
-
-    InetSocketAddress authority() { return authority; }
-
-    void setH2Upgrade() {
-        Http2ClientImpl h2client = client.client2();
-        systemHeaders.setHeader("Connection", "Upgrade, HTTP2-Settings");
-        systemHeaders.setHeader("Upgrade", "h2c");
-        systemHeaders.setHeader("HTTP2-Settings", h2client.getSettingsString());
-    }
-
-    private synchronized void receiving() {
-        if (receiving) {
-            throw new IllegalStateException("already receiving response");
-        }
-        receiving = true;
-    }
-
-    synchronized Stream.PushGroup<?> pushGroup() {
-        return pushGroup;
-    }
-
-    /*
-     * Response filters may result in a new HttpRequestImpl being created
-     * (but still associated with the same API HttpRequest) and the process
-     * is repeated.
-     */
-    @Override
-    public HttpResponse response() throws IOException, InterruptedException {
-        receiving(); // TODO: update docs
-        if (System.getSecurityManager() != null) {
-            acc = AccessController.getContext();
-        }
-        return exchange.response();
-    }
-
-    @Override
-    public synchronized CompletableFuture<HttpResponse> responseAsync() {
-        receiving(); // TODO: update docs
-        if (System.getSecurityManager() != null) {
-            acc = AccessController.getContext();
-        }
-        return exchange.responseAsync(null)
-            .thenApply((r) -> (HttpResponse)r);
-    }
-
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public synchronized <U> CompletableFuture<U>
-    multiResponseAsync(MultiProcessor<U> rspproc) {
-        if (System.getSecurityManager() != null) {
-            acc = AccessController.getContext();
-        }
-        this.pushGroup = new Stream.PushGroup<>(rspproc, this);
-        CompletableFuture<HttpResponse> cf = pushGroup.mainResponse();
-        responseAsync()
-            .whenComplete((HttpResponse r, Throwable t) -> {
-                if (r != null)
-                    cf.complete(r);
-                else
-                    cf.completeExceptionally(t);
-                pushGroup.pushError(t);
-            });
-        return (CompletableFuture<U>)pushGroup.groupResult();
-    }
-
-    @Override
-    public boolean expectContinue() { return expectContinue; }
-
-    public boolean requestHttp2() {
-        return version.equals(HttpClient.Version.HTTP_2);
-        //return client.getHttp2Allowed();
-    }
-
-    AccessControlContext getAccessControlContext() { return acc; }
-
-    InetSocketAddress proxy() {
-        ProxySelector ps = this.proxy;
-        if (ps == null) {
-            ps = client.proxy().orElse(null);
-        }
-        if (ps == null || method.equalsIgnoreCase("CONNECT")) {
-            return null;
-        }
-        return (InetSocketAddress)ps.select(uri).get(0).address();
-    }
-
-    boolean secure() { return secure; }
-
-    void isWebSocket(boolean is) {
-        isWebSocket = is;
-    }
-
-    boolean isWebSocket() {
-        return isWebSocket;
-    }
-
-    /** Returns the follow-redirects setting for this request. */
-    @Override
-    public java.net.http.HttpClient.Redirect followRedirects() {
-        return getRedirects(followRedirects);
-    }
-
-    HttpRedirectImpl followRedirectsImpl() { return followRedirects; }
-
-    /**
-     * Returns the request method for this request. If not set explicitly,
-     * the default method for any request is "GET".
-     */
-    @Override
-    public String method() { return method; }
-
-    @Override
-    public URI uri() { return uri; }
-
-    HttpHeaders getUserHeaders() { return userHeaders; }
-
-    HttpHeadersImpl getSystemHeaders() { return systemHeaders; }
-
-    HttpClientImpl getClient() { return client; }
-
-    BodyProcessor requestProcessor() { return requestProcessor; }
-
-    @Override
-    public Version version() { return version; }
-
-    void addSystemHeader(String name, String value) {
-        systemHeaders.addHeader(name, value);
-    }
-
-    void setSystemHeader(String name, String value) {
-        systemHeaders.setHeader(name, value);
-    }
-
-    long timeval() { return timeval; }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponse.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,985 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InputStream;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.LongConsumer;
-import javax.net.ssl.SSLParameters;
-
-/**
- * Represents a response to a {@link HttpRequest}. A {@code HttpResponse} is
- * available when the response status code and headers have been received, but
- * before the response body is received.
- *
- * <p> Methods are provided in this class for accessing the response headers,
- * and status code immediately and also methods for retrieving the response body.
- * Static methods are provided which implement {@link BodyProcessor} for
- * standard body types such as {@code String, byte arrays, files}.
- *
- * <p> The {@link #body(BodyProcessor) body} or {@link #bodyAsync(BodyProcessor)
- * bodyAsync} which retrieve any response body must be called to ensure that the
- * TCP connection can be re-used subsequently, and any response trailers
- * accessed, if they exist, unless it is known that no response body was received.
- *
- * @since 9
- */
-public abstract class HttpResponse {
-
-    HttpResponse() { }
-
-    /**
-     * Returns the status code for this response.
-     *
-     * @return the response code
-     */
-    public abstract int statusCode();
-
-    /**
-     * Returns the {@link HttpRequest} for this response.
-     *
-     * @return the request
-     */
-    public abstract HttpRequest request();
-
-    /**
-     * Returns the received response headers.
-     *
-     * @return the response headers
-     */
-    public abstract HttpHeaders headers();
-
-    /**
-     * Returns the received response trailers, if there are any. This must only
-     * be called after the response body has been received.
-     *
-     * @return the response trailers (may be empty)
-     * @throws IllegalStateException if the response body has not been received
-     *                               yet
-     */
-    public abstract HttpHeaders trailers();
-
-    /**
-     * Returns the body, blocking if necessary. The type T is determined by the
-     * {@link BodyProcessor} implementation supplied. The body object will be
-     * returned immediately if it is a type (such as {@link java.io.InputStream}
-     * which reads the data itself. If the body object represents the fully read
-     * body then it blocks until it is fully read.
-     *
-     * @param <T> the type of the returned body object
-     * @param processor the processor to handle the response body
-     * @return the body
-     * @throws java.io.UncheckedIOException if an I/O error occurs reading the
-     *                                      response
-     */
-    public abstract <T> T body(BodyProcessor<T> processor);
-
-    /**
-     * Returns a {@link java.util.concurrent.CompletableFuture} of type T. This
-     * always returns immediately and the future completes when the body object
-     * is available. The body will be available immediately if it is a type
-     * (such as {@link java.io.InputStream} which reads the data itself. If the
-     * body object represents the fully read body then it will not be available
-     * until it is fully read.
-     *
-     * @param <T> the type of the returned body object
-     * @param processor the processor to handle the response body
-     * @return a CompletableFuture
-     */
-    public abstract <T> CompletableFuture<T> bodyAsync(BodyProcessor<T> processor);
-
-    /**
-     * Returns the {@link javax.net.ssl.SSLParameters} in effect for this
-     * response. Returns {@code null} if this is not a https response.
-     *
-     * @return the SSLParameters associated with the response
-     */
-    public abstract SSLParameters sslParameters();
-
-    /**
-     * Returns the URI that the response was received from. This may be
-     * different from the request URI if redirection occurred.
-     *
-     * @return the URI of the response
-     */
-    public abstract URI uri();
-
-    /**
-     * Returns the HTTP protocol version that was used for this response.
-     *
-     * @return HTTP protocol version
-     */
-    public abstract HttpClient.Version version();
-
-    /**
-     * Returns a {@link BodyProcessor}&lt;{@link java.nio.file.Path}&gt; where
-     * the file is created if it does not already exist. When the Path object is
-     * returned, the body has been completely written to the file.
-     *
-     * @param file the file to store the body in
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<Path> asFile(Path file) {
-        return asFile(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
-    }
-
-    /**
-     * Returns a {@link BodyProcessor}&lt;{@link java.nio.file.Path}&gt; where
-     * the download directory is specified, but the filename is obtained from
-     * the Content-Disposition response header. The Content-Disposition header
-     * must specify the <i>attachment</i> type and must also contain a
-     * <i>filename</i> parameter. If the filename specifies multiple path
-     * components only the final component is used as the filename (with the
-     * given directory name). When the Path object is returned, the body has
-     * been completely written to the file. The returned Path is the combination
-     * of the supplied directory name and the file name supplied by the server.
-     * If the destination directory does not exist or cannot be written to, then
-     * the response will fail with an IOException.
-     *
-     * @param directory the directory to store the file in
-     * @param openOptions open options
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<Path> asFileDownload(Path directory,
-                                                     OpenOption... openOptions) {
-        return new AbstractResponseProcessor<Path>() {
-
-            FileChannel fc;
-            Path file;
-
-            @Override
-            public Path onResponseBodyStartImpl(long contentLength,
-                                                HttpHeaders headers)
-                throws IOException
-            {
-                String dispoHeader = headers.firstValue("Content-Disposition")
-                        .orElseThrow(() -> new IOException("No Content-Disposition"));
-                if (!dispoHeader.startsWith("attachment;")) {
-                    throw new IOException("Unknown Content-Disposition type");
-                }
-                int n = dispoHeader.indexOf("filename=");
-                if (n == -1) {
-                    throw new IOException("Bad Content-Disposition type");
-                }
-                int lastsemi = dispoHeader.lastIndexOf(';');
-                String disposition;
-                if (lastsemi < n)
-                    disposition = dispoHeader.substring(n + 9);
-                else
-                    disposition = dispoHeader.substring(n + 9, lastsemi);
-                file = Paths.get(directory.toString(), disposition);
-                fc = FileChannel.open(file, openOptions);
-                return null;
-            }
-
-            @Override
-            public void onResponseBodyChunkImpl(ByteBuffer b) throws IOException {
-                fc.write(b);
-            }
-
-            @Override
-            public Path onResponseComplete() throws IOException {
-                fc.close();
-                return file;
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-                try {
-                    if (fc != null) {
-                        fc.close();
-                    }
-                } catch (IOException e) {
-                }
-            }
-        };
-    }
-
-    /**
-     * Returns a {@link BodyProcessor}&lt;{@link java.nio.file.Path}&gt;.
-     *
-     * <p> {@link HttpResponse}s returned using this response processor complete
-     * after the entire response, including body has been read.
-     *
-     * @param file the filename to store the body in
-     * @param openOptions any options to use when opening/creating the file
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<Path> asFile(Path file,
-                                             OpenOption... openOptions) {
-        return new AbstractResponseProcessor<Path>() {
-
-            FileChannel fc;
-
-            @Override
-            public Path onResponseBodyStartImpl(long contentLength,
-                                                HttpHeaders headers)
-                throws IOException
-            {
-                fc = FileChannel.open(file, openOptions);
-                return null;
-            }
-
-            @Override
-            public void onResponseBodyChunkImpl(ByteBuffer b)
-                throws IOException
-            {
-                fc.write(b);
-            }
-
-            @Override
-            public Path onResponseComplete() throws IOException {
-                fc.close();
-                return file;
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-                try {
-                    if (fc != null) {
-                        fc.close();
-                    }
-                } catch (IOException e) {
-                }
-            }
-        };
-    }
-
-    static class ByteArrayResponseProcessor {
-
-        static final int INITIAL_BUFLEN = 1024;
-
-        byte[] buffer;
-        int capacity;
-        boolean knownLength;
-        int position;
-
-        ByteArrayResponseProcessor() { }
-
-        public byte[] onStart(long contentLength) throws IOException {
-            if (contentLength > Integer.MAX_VALUE) {
-                throw new IllegalArgumentException(
-                        "byte array response limited to MAX_INT size");
-            }
-            capacity = (int) contentLength;
-            if (capacity != -1) {
-                buffer = new byte[capacity];
-                knownLength = true;
-            } else {
-                buffer = new byte[INITIAL_BUFLEN];
-                capacity = INITIAL_BUFLEN;
-                knownLength = false;
-            }
-            position = 0;
-            return null;
-        }
-
-        public void onBodyContent(ByteBuffer b) throws IOException {
-            int toCopy = b.remaining();
-            int size = capacity;
-            if (toCopy > capacity - position) {
-                // resize
-                size += toCopy * 2;
-            }
-            if (size != capacity) {
-                if (knownLength) {
-                    // capacity should have been right from start
-                    throw new IOException("Inconsistent content length");
-                }
-                byte[] newbuf = new byte[size];
-                System.arraycopy(buffer, 0, newbuf, 0, position);
-                buffer = newbuf;
-                capacity = size;
-            }
-            int srcposition = b.arrayOffset() + b.position();
-            System.arraycopy(b.array(), srcposition, buffer, position, toCopy);
-            b.position(b.limit());
-            position += toCopy;
-        }
-
-        public byte[] onComplete() throws IOException {
-            if (knownLength) {
-                if (position != capacity) {
-                    throw new IOException("Wrong number of bytes received");
-                }
-                return buffer;
-            }
-            byte[] buf1 = new byte[position];
-            System.arraycopy(buffer, 0, buf1, 0, position);
-            return buf1;
-        }
-
-        public void onError(Throwable t) {
-            // TODO:
-        }
-    }
-
-    static final byte[] EMPTY = new byte[0];
-
-    /**
-     * Returns a response processor which supplies the response body to the
-     * given Consumer. Each time data is received the consumer is invoked with a
-     * byte[] containing at least one byte of data. After the final buffer is
-     * received, the consumer is invoked one last time, with an empty byte
-     * array.
-     *
-     * @param consumer a Consumer to accept the response body
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<Void> asByteArrayConsumer(Consumer<byte[]> consumer) {
-        return new AbstractResponseProcessor<Void>() {
-            @Override
-            public Void onResponseBodyStartImpl(long clen,
-                                                HttpHeaders h)
-                throws IOException
-            {
-                return null;
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-            }
-
-            @Override
-            public void onResponseBodyChunkImpl(ByteBuffer b) throws IOException {
-                if (!b.hasRemaining()) {
-                    return;
-                }
-                byte[] buf = new byte[b.remaining()];
-                b.get(buf);
-                consumer.accept(buf);
-            }
-
-            @Override
-            public Void onResponseComplete() throws IOException {
-                consumer.accept(EMPTY);
-                return null;
-            }
-        };
-    }
-
-    /**
-     * Returns a BodyProcessor which delivers the response data to a
-     * {@link java.util.concurrent.Flow.Subscriber}{@code ByteBuffer}.
-     * <p>
-     * The given {@code Supplier<U>} is invoked when the Flow is completed in
-     * order to convert the flow data into the U object that is returned as the
-     * response body.
-     *
-     * @param <U> the response body type
-     * @param subscriber the Flow.Subscriber
-     * @param bufferSize the maximum number of bytes of data to be supplied in
-     * each ByteBuffer
-     * @param bodySupplier an object that converts the received data to the body
-     * type U.
-     * @return a BodyProcessor
-     *
-     * public static <U> BodyProcessor<Flow.Subscriber<ByteBuffer>>
-     * asFlowSubscriber() {
-     *
-     * return new BodyProcessor<U>() { Flow.Subscriber<ByteBuffer> subscriber;
-     * LongConsumer flowController; FlowSubscription subscription; Supplier<U>
-     * bodySupplier; int bufferSize; // down-stream Flow window. long
-     * buffersWindow; // upstream window long bytesWindow;
-     * LinkedList<ByteBuffer> buffers = new LinkedList<>();
-     *
-     * class FlowSubscription implements Subscription { int recurseLevel = 0;
-     * @Override public void request(long n) { boolean goodToGo = recurseLevel++
-     * == 0;
-     *
-     * while (goodToGo && buffers.size() > 0 && n > 0) { ByteBuffer buf =
-     * buffers.get(0); subscriber.onNext(buf); n--; } buffersWindow += n;
-     * flowController.accept(n * bufferSize); recurseLevel--; }
-     *
-     * @Override public void cancel() { // ?? set flag and throw exception on
-     * next receipt of buffer } }
-     *
-     * @Override public U onResponseBodyStart(long contentLength, HttpHeaders
-     * responseHeaders, LongConsumer flowController) throws IOException {
-     * this.subscriber = subscriber; this.flowController = flowController;
-     * this.subscription = new FlowSubscription(); this.bufferSize = bufferSize;
-     * subscriber.onSubscribe(subscription); return null; }
-     *
-     * @Override public void onResponseError(Throwable t) {
-     * subscriber.onError(t); }
-     *
-     * @Override public void onResponseBodyChunk(ByteBuffer b) throws
-     * IOException { if (buffersWindow > 0) { buffersWindow --;
-     * subscriber.onNext(b); } else { buffers.add(b); // or could combine
-     * buffers? } }
-     *
-     * @Override public U onResponseComplete() throws IOException {
-     * subscriber.onComplete(); return bodySupplier.get(); } }; }
-     */
-    private static final ByteBuffer EOF = ByteBuffer.allocate(0);
-    private static final ByteBuffer CLOSED = ByteBuffer.allocate(0);
-
-    // prototype using ByteBuffer based flow control. InputStream feeds off a
-    // BlockingQueue. Size of Q is determined from the the bufsize (bytes) and
-    // the default ByteBuffer size. bufsize should be a reasonable multiple of
-    // ByteBuffer size to prevent underflow/starvation. The InputStream updates
-    // the flowControl window by one as each ByteBuffer is fully consumed.
-    // Special sentinels are used to indicate stream closed and EOF.
-    /**
-     * Returns a response body processor which provides an InputStream to read
-     * the body.
-     *
-     * @implNote This mechanism is provided primarily for backwards
-     * compatibility for code that expects InputStream. It is recommended for
-     * better performance to use one of the other response processor
-     * implementations.
-     *
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<InputStream> asInputStream() {
-        return new BodyProcessor<InputStream>() {
-            int queueSize = 2;
-            private volatile Throwable throwable;
-
-            BlockingQueue<ByteBuffer> queue  = new LinkedBlockingQueue<>();
-
-            private void closeImpl() {
-                try {
-                    queue.put(CLOSED);
-                } catch (InterruptedException e) { }
-            }
-
-            @Override
-            public InputStream onResponseBodyStart(long contentLength,
-                                                   HttpHeaders responseHeaders,
-                                                   LongConsumer flowController)
-                throws IOException
-            {
-                flowController.accept(queueSize);
-
-                return new InputStream() {
-                    ByteBuffer buffer;
-
-                    @Override
-                    public int read() throws IOException {
-                        byte[] bb = new byte[1];
-                        int n = read(bb, 0, 1);
-                        if (n == -1) {
-                            return -1;
-                        } else {
-                            return bb[0];
-                        }
-                    }
-
-                    @Override
-                    public int read(byte[] bb) throws IOException {
-                        return read(bb, 0, bb.length);
-                    }
-
-                    @Override
-                    public int read(byte[] bb, int offset, int length)
-                        throws IOException
-                    {
-                        int n;
-                        if (getBuffer()) {
-                            return -1; // EOF
-                        } else {
-                            int remaining = buffer.remaining();
-                            if (length >= remaining) {
-                                buffer.get(bb, offset, remaining);
-                                return remaining;
-                            } else {
-                                buffer.get(bb, offset, length);
-                                return length;
-                            }
-                        }
-                    }
-
-                    @Override
-                    public void close() {
-                        closeImpl();
-                    }
-
-                    private boolean getBuffer() throws IOException {
-                        while (buffer == null || (buffer != EOF &&
-                                buffer != CLOSED && !buffer.hasRemaining())) {
-                            try {
-                                buffer = queue.take();
-                                flowController.accept(1);
-                            } catch (InterruptedException e) {
-                                throw new IOException(e);
-                            }
-                        }
-                        if (buffer == CLOSED) {
-                            if (throwable != null) {
-                                if (throwable instanceof IOException) {
-                                    throw (IOException) throwable;
-                                } else {
-                                    throw new IOException(throwable);
-                                }
-                            }
-                            throw new IOException("Closed");
-                        }
-
-                        if (buffer == EOF) {
-                            return true; // EOF
-                        }
-                        return false; // not EOF
-                    }
-
-                };
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-                throwable = t;
-                closeImpl();
-            }
-
-            @Override
-            public void onResponseBodyChunk(ByteBuffer b) throws IOException {
-                try {
-                    queue.put(Utils.copy(b));
-                } catch (InterruptedException e) {
-                    // shouldn't happen as queue should never block
-                    throw new IOException(e);
-                }
-            }
-
-            @Override
-            public InputStream onResponseComplete() throws IOException {
-                try {
-                    queue.put(EOF);
-                } catch (InterruptedException e) {
-                    throw new IOException(e); // can't happen
-                }
-                return null;
-            }
-
-        };
-    }
-
-    /**
-     * Common super class that takes care of flow control
-     *
-     * @param <T>
-     */
-    private static abstract class AbstractResponseProcessor<T>
-        implements BodyProcessor<T>
-    {
-        LongConsumer flowController;
-
-        @Override
-        public final T onResponseBodyStart(long contentLength,
-                                           HttpHeaders responseHeaders,
-                                           LongConsumer flowController)
-            throws IOException
-        {
-            this.flowController = flowController;
-            flowController.accept(1);
-            return onResponseBodyStartImpl(contentLength, responseHeaders);
-        }
-
-        public abstract T onResponseBodyStartImpl(long contentLength,
-                                                  HttpHeaders responseHeaders)
-            throws IOException;
-
-        public abstract void onResponseBodyChunkImpl(ByteBuffer b)
-            throws IOException;
-
-        @Override
-        public final void onResponseBodyChunk(ByteBuffer b) throws IOException {
-            onResponseBodyChunkImpl(b);
-            flowController.accept(1);
-        }
-    }
-
-    /**
-     * Returns a {@link BodyProcessor}&lt;byte[]&gt; which returns the response
-     * body as a {@code byte array}.
-     *
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<byte[]> asByteArray() {
-        ByteArrayResponseProcessor brp = new ByteArrayResponseProcessor();
-
-        return new AbstractResponseProcessor<byte[]>() {
-
-            @Override
-            public byte[] onResponseBodyStartImpl(long contentLength,
-                                                  HttpHeaders h)
-                throws IOException
-            {
-                brp.onStart(contentLength);
-                return null;
-            }
-
-            @Override
-            public void onResponseBodyChunkImpl(ByteBuffer b)
-                throws IOException
-            {
-                brp.onBodyContent(b);
-            }
-
-            @Override
-            public byte[] onResponseComplete() throws IOException {
-                return brp.onComplete();
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-                brp.onError(t);
-            }
-        };
-    }
-
-    /**
-     * Returns a response processor which decodes the body using the character
-     * set specified in the {@code Content-encoding} response header. If there
-     * is no such header, or the character set is not supported, then
-     * {@link java.nio.charset.StandardCharsets#ISO_8859_1 ISO_8859_1} is used.
-     *
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<String> asString() {
-        return asString(null);
-    }
-
-    /**
-     * Returns a MultiProcessor that handles multiple responses, writes the
-     * response bodies to files and which returns an aggregate response object
-     * that is a {@code Map<URI,Path>}. The keyset of the Map represents the
-     * URIs of the original request and any additional requests generated by the
-     * server. The values are the paths of the destination files. Each path uses
-     * the URI path of the request offset from the destination parent directory
-     * provided.
-     *
-     * <p> All incoming additional requests (push promises) are accepted by this
-     * multi response processor. Errors are effectively ignored and any failed
-     * responses are simply omitted from the result Map. Other implementations
-     * of MultiProcessor can handle these situations
-     *
-     * <p><b>Example usage</b>
-     * <pre>
-     * {@code
-     *    CompletableFuture<Map<URI,Path>> cf =
-     *    HttpRequest.create(new URI("https://www.foo.com/"))
-     *               .version(Version.HTTP2)
-     *               .GET()
-     *               .sendAsyncMulti(HttpResponse.multiFile("/usr/destination"));
-     *
-     *    Map<URI,Path> results = cf.join();
-     * }
-     * </pre>
-     *
-     * @param destination the destination parent directory of all response
-     * bodies
-     * @return a MultiProcessor
-     */
-    public static MultiProcessor<Map<URI, Path>> multiFile(Path destination) {
-
-        return new MultiProcessor<Map<URI, Path>>() {
-            Map<URI, CompletableFuture<Path>> bodyCFs = new HashMap<>();
-
-            Map<URI, Path> results = new HashMap<>();
-
-            @Override
-            public BiFunction<HttpRequest, CompletableFuture<HttpResponse>, Boolean>
-            onStart(HttpRequest mainRequest,
-                    CompletableFuture<HttpResponse> response) {
-                bodyCFs.put(mainRequest.uri(), getBody(mainRequest, response));
-                return (HttpRequest additional, CompletableFuture<HttpResponse> cf) -> {
-                    CompletableFuture<Path> bcf = getBody(additional, cf);
-                    bodyCFs.put(additional.uri(), bcf);
-                    // we accept all comers
-                    return true;
-                };
-            }
-
-            private CompletableFuture<Path> getBody(HttpRequest req,
-                                                    CompletableFuture<? extends HttpResponse> cf) {
-                URI u = req.uri();
-                String path = u.getPath();
-                if (path.startsWith("/"))
-                    path = path.substring(1);
-                final String fpath = path;
-                return cf.thenCompose((HttpResponse resp) -> {
-                    return resp.bodyAsync(HttpResponse.asFile(destination.resolve(fpath)));
-                });
-            }
-
-            @Override
-            public Map<URI, Path> onComplete() {
-                // all CFs have completed normally or in error.
-                Set<Map.Entry<URI, CompletableFuture<Path>>> entries = bodyCFs.entrySet();
-                for (Map.Entry<URI, CompletableFuture<Path>> entry : entries) {
-                    CompletableFuture<Path> v = entry.getValue();
-                    URI uri = entry.getKey();
-                    if (v.isDone() && !v.isCompletedExceptionally()) {
-                        results.put(uri, v.join());
-                    }
-                }
-                return results;
-            }
-        };
-    }
-
-    /**
-     * Returns a {@link BodyProcessor}&lt;{@link String}&gt;.
-     *
-     * @param charset the name of the charset to interpret the body as. If
-     * {@code null} then the processor tries to determine the character set from
-     * the {@code Content-encoding} header. If that charset is not supported
-     * then {@link java.nio.charset.StandardCharsets#ISO_8859_1 ISO_8859_1} is
-     * used.
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<String> asString(Charset charset) {
-
-        ByteArrayResponseProcessor brp = new ByteArrayResponseProcessor();
-
-        return new AbstractResponseProcessor<String>() {
-            Charset cs = charset;
-            HttpHeaders headers;
-
-            @Override
-            public String onResponseBodyStartImpl(long contentLength,
-                                                  HttpHeaders h)
-                throws IOException
-            {
-                headers = h;
-                brp.onStart(contentLength);
-                return null;
-            }
-
-            @Override
-            public void onResponseBodyChunkImpl(ByteBuffer b) throws IOException {
-                brp.onBodyContent(b);
-            }
-
-            @Override
-            public String onResponseComplete() throws IOException {
-                byte[] buf = brp.onComplete();
-                if (cs == null) {
-                    cs = headers.firstValue("Content-encoding")
-                                .map((String s) -> Charset.forName(s))
-                                .orElse(StandardCharsets.ISO_8859_1);
-                }
-                return new String(buf, cs);
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-                brp.onError(t);
-            }
-
-        };
-    }
-
-    /**
-     * Returns a response processor which ignores the response body.
-     *
-     * @return a {@code BodyProcessor}
-     */
-    public static BodyProcessor<Void> ignoreBody() {
-        return asByteArrayConsumer((byte[] buf) -> { /* ignore */ });
-    }
-
-    /**
-     * A processor for response bodies, which determines the type of the
-     * response body returned from {@link HttpResponse}. Response processors can
-     * either return an object that represents the body itself (after it has
-     * been read) or else an object that is used to read the body (such as an
-     * {@code InputStream}). The parameterized type {@code <T>} is the type of
-     * the returned body object from
-     * {@link HttpResponse#body(BodyProcessor) HttpResponse.body} and
-     * (indirectly) from {@link HttpResponse#bodyAsync(BodyProcessor)
-     * HttpResponse.bodyAsync}.
-     *
-     * <p> Implementations of this interface are provided in {@link HttpResponse}
-     * which write responses to {@code String, byte[], File, Consumer<byte[]>}.
-     * Custom implementations can also be used.
-     *
-     * <p> The methods of this interface may be called from multiple threads,
-     * but only one method is invoked at a time, and behaves as if called from
-     * one thread.
-     *
-     * @param <T> the type of the response body
-     *
-     * @since 9
-     */
-    public interface BodyProcessor<T> {
-
-        /**
-         * Called immediately before the response body is read. If {@code <T>}
-         * is an object used to read or accept the response body, such as a
-         * {@code Consumer} or {@code InputStream} then it should be returned
-         * from this method, and the body object will be returned before any
-         * data is read. If {@code <T>} represents the body itself after being
-         * read, then this method must return {@code null} and the body will be
-         * returned from {@link #onResponseComplete()}. In both cases, the
-         * actual body data is provided by the
-         * {@link #onResponseBodyChunk(ByteBuffer) onResponseBodyChunk} method
-         * in exactly the same way.
-         *
-         * <p> flowController is a consumer of long values and is used for
-         * updating a flow control window as follows. The window represents the
-         * number of times
-         * {@link #onResponseBodyChunk(java.nio.ByteBuffer) onResponseBodyChunk}
-         * may be called before receiving further updates to the window. Each
-         * time it is called, the window is reduced by {@code 1}. When the
-         * window reaches zero {@code onResponseBodyChunk()} will not be called
-         * again until the window has opened again with further calls to
-         * flowController.accept().
-         * {@link java.util.function.LongConsumer#accept(long) flowcontroller.accept()}
-         * must be called to open (increase) the window by the specified amount.
-         * The initial value is zero. This implies that if {@code
-         * onResponseBodyStart()} does not call {@code flowController.accept()}
-         * with a positive value no data will ever be delivered.
-         *
-         * @param contentLength {@code -1} signifies unknown content length.
-         *                      Otherwise, a positive integer, or zero.
-         * @param responseHeaders the response headers
-         * @param flowController a LongConsumer used to update the flow control
-         *                       window
-         * @return {@code null} or an object that can be used to read the
-         *         response body.
-         * @throws IOException if an exception occurs starting the response
-         *                     body receive
-         */
-        T onResponseBodyStart(long contentLength,
-                              HttpHeaders responseHeaders,
-                              LongConsumer flowController)
-            throws IOException;
-
-        /**
-         * Called if an error occurs while reading the response body. This
-         * terminates the operation and no further calls will occur after this.
-         *
-         * @param t the Throwable
-         */
-        void onResponseError(Throwable t);
-
-        /**
-         * Called for each buffer of data received for this response.
-         * ByteBuffers can be reused as soon as this method returns.
-         *
-         * @param b a ByteBuffer whose position is at the first byte that can be
-         *          read, and whose limit is after the last byte that can be read
-         * @throws IOException in case of I/O error
-         */
-        void onResponseBodyChunk(ByteBuffer b) throws IOException;
-
-        /**
-         * Called after the last time
-         * {@link #onResponseBodyChunk(java.nio.ByteBuffer)} has been called and
-         * returned indicating that the entire content has been read. This
-         * method must return an object that represents or contains the response
-         * body just received, but only if an object was not returned from
-         * {@link #onResponseBodyStart(long, HttpHeaders, LongConsumer)
-         * onResponseBodyStart}.
-         *
-         * @return a T, or {@code null} if an object was already returned
-         * @throws IOException in case of I/O error
-         */
-        T onResponseComplete() throws IOException;
-    }
-
-    /**
-     * A response processor for a HTTP/2 multi response. A multi response
-     * comprises a main response, and zero or more additional responses. Each
-     * additional response is sent by the server in response to requests that
-     * the server also generates. Additional responses are typically resources
-     * that the server guesses the client will need which are related to the
-     * initial request.
-     *
-     * <p>The server generated requests are also known as <i>push promises</i>.
-     * The server is permitted to send any number of these requests up to the
-     * point where the main response is fully received. Therefore, after
-     * completion of the main response body, the final number of additional
-     * responses is known. Additional responses may be cancelled, but given that
-     * the server does not wait for any acknowledgment before sending the
-     * response, this must be done quickly to avoid unnecessary data transmission.
-     *
-     * <p> {@code MultiProcessor}s are parameterised with a type {@code T} which
-     * represents some meaningful aggregate of the responses received. This
-     * would typically be a Collection of response or response body objects. One
-     * example implementation can be found at {@link
-     * HttpResponse#multiFile(java.nio.file.Path)}.
-     *
-     * @param <T> a type representing the aggregated results
-     *
-     * @since 9
-     */
-    public interface MultiProcessor<T> {
-
-        /**
-         * Called before or soon after a multi request is sent. The request that
-         * initiated the multi response is supplied, as well as a
-         * CompletableFuture for the main response. The implementation of this
-         * method must return a BiFunction which is called once for each push
-         * promise received.
-         *
-         * <p> The parameters to the {@code BiFunction} are the {@code HttpRequest}
-         * for the push promise and a {@code CompletableFuture} for its
-         * response. The function must return a Boolean indicating whether the
-         * push promise has been accepted (true) or should be canceled (false).
-         * The CompletableFutures for any canceled pushes are themselves
-         * completed exceptionally soon after the function returns.
-         *
-         * @param mainRequest the main request
-         * @param response a CompletableFuture for the main response
-         * @return a BiFunction that is called for each push promise
-         */
-        BiFunction<HttpRequest, CompletableFuture<HttpResponse>, Boolean>
-        onStart(HttpRequest mainRequest,
-                CompletableFuture<HttpResponse> response);
-
-        /**
-         * Called after all responses associated with the multi response have
-         * been fully processed, including response bodies.
-         *
-         * <p> Example types for {@code T} could be Collections of response body
-         * types or {@code Map}s from request {@code URI} to a response body
-         * type.
-         *
-         * @return the aggregate response object
-         */
-        T onComplete();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.URI;
-import java.nio.ByteBuffer;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.LongConsumer;
-import javax.net.ssl.SSLParameters;
-
-/**
- * The implementation class for HttpResponse
- */
-class HttpResponseImpl extends HttpResponse {
-
-    int responseCode;
-    Exchange exchange;
-    HttpRequestImpl request;
-    HttpHeaders headers;
-    HttpHeaders trailers;
-    SSLParameters sslParameters;
-    URI uri;
-    HttpClient.Version version;
-    AccessControlContext acc;
-    RawChannel rawchan;
-    HttpConnection connection;
-    final Stream stream;
-
-    public HttpResponseImpl(int responseCode, Exchange exch, HttpHeaders headers,
-            HttpHeaders trailers, SSLParameters sslParameters,
-            HttpClient.Version version, HttpConnection connection) {
-        this.responseCode = responseCode;
-        this.exchange = exch;
-        this.request = exchange.request();
-        this.headers = headers;
-        this.trailers = trailers;
-        this.sslParameters = sslParameters;
-        this.uri = request.uri();
-        this.version = version;
-        this.connection = connection;
-        this.stream = null;
-    }
-
-    // A response to a PUSH_PROMISE
-    public HttpResponseImpl(int responseCode, HttpRequestImpl pushRequest,
-            ImmutableHeaders headers,
-            Stream stream, SSLParameters sslParameters) {
-        this.responseCode = responseCode;
-        this.exchange = null;
-        this.request = pushRequest;
-        this.headers = headers;
-        this.trailers = null;
-        this.sslParameters = sslParameters;
-        this.uri = request.uri(); // TODO: take from headers
-        this.version = HttpClient.Version.HTTP_2;
-        this.connection = null;
-        this.stream = stream;
-    }
-
-    @Override
-    public int statusCode() {
-        return responseCode;
-    }
-
-    @Override
-    public HttpRequestImpl request() {
-        return request;
-    }
-
-    @Override
-    public HttpHeaders headers() {
-        return headers;
-    }
-
-    @Override
-    public HttpHeaders trailers() {
-        return trailers;
-    }
-
-
-    @Override
-    public <T> T body(java.net.http.HttpResponse.BodyProcessor<T> processor) {
-        try {
-            if (exchange != null) {
-                return exchange.responseBody(processor);
-            } else {
-                return stream.responseBody(processor);
-            }
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-    @Override
-    public <T> CompletableFuture<T> bodyAsync(java.net.http.HttpResponse.BodyProcessor<T> processor) {
-        acc = AccessController.getContext();
-        if (exchange != null)
-            return exchange.responseBodyAsync(processor);
-        else
-            return stream.responseBodyAsync(processor);
-    }
-
-    @Override
-    public SSLParameters sslParameters() {
-        return sslParameters;
-    }
-
-    public AccessControlContext getAccessControlContext() {
-        return acc;
-    }
-
-    @Override
-    public URI uri() {
-        return uri;
-    }
-
-    @Override
-    public HttpClient.Version version() {
-        return version;
-    }
-    // keepalive flag determines whether connection is closed or kept alive
-    // by reading/skipping data
-
-    public static java.net.http.HttpResponse.BodyProcessor<Void> ignoreBody(boolean keepalive) {
-        return new java.net.http.HttpResponse.BodyProcessor<Void>() {
-
-            @Override
-            public Void onResponseBodyStart(long clen, HttpHeaders h,
-                    LongConsumer flowController) throws IOException {
-                return null;
-            }
-
-            @Override
-            public void onResponseBodyChunk(ByteBuffer b) throws IOException {
-            }
-
-            @Override
-            public Void onResponseComplete() throws IOException {
-                return null;
-            }
-
-            @Override
-            public void onResponseError(Throwable t) {
-            }
-        };
-    }
-
-    /**
-     *
-     * @return
-     */
-    RawChannel rawChannel() throws IOException {
-        if (rawchan == null) {
-            rawchan = new RawChannelImpl(request.client(), connection);
-        }
-        return rawchan;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpTimeoutException.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-/**
- * Thrown when a response is not received within a specified time period.
- */
-public class HttpTimeoutException extends IOException {
-
-    private static final long serialVersionUID = 981344271622632951L;
-
-    public HttpTimeoutException(String message) {
-        super(message);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ImmutableHeaders.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.TreeMap;
-import java.util.function.Predicate;
-
-/**
- * Immutable HttpHeaders constructed from mutable HttpHeadersImpl.
- */
-
-class ImmutableHeaders implements HttpHeaders {
-
-    private final Map<String,List<String>> map;
-
-    @SuppressWarnings("unchecked")
-    ImmutableHeaders() {
-        map = (Map<String,List<String>>)Collections.EMPTY_MAP;
-    }
-    // TODO: fix lower case issue. Must be lc for http/2 compares ignoreCase for http/1
-    ImmutableHeaders(HttpHeadersImpl h, Predicate<String> keyAllowed) {
-        Map<String,List<String>> src = h.directMap();
-        Map<String,List<String>> m = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
-        src.forEach((key, value) -> {
-            if (keyAllowed.test(key))
-                m.put(key, Collections.unmodifiableList(value));
-        });
-        map = Collections.unmodifiableMap(m);
-    }
-
-    @Override
-    public Optional<String> firstValue(String name) {
-        List<String> l = map.get(name);
-        String v = l == null ? null : l.get(0);
-        return Optional.ofNullable(v);
-    }
-
-    @Override
-    public Optional<Long> firstValueAsLong(String name) {
-        return firstValue(name).map((v -> Long.parseLong(v)));
-    }
-
-    @Override
-    public List<String> allValues(String name) {
-        return map.get(name);
-    }
-
-    @Override
-    public Map<String, List<String>> map() {
-        return map;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Log.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.Locale;
-
-/**
- * -Djava.net.HttpClient.log=
- *          errors,requests,headers,
- *          frames[:type:type2:..],content,ssl,trace
- *
- * Any of errors, requests, headers or content are optional.
- *
- * Other handlers may be added. All logging is at level INFO
- *
- * Logger name is "java.net.http.HttpClient"
- */
-// implements System.Logger in order to be skipped when printing the caller's
-// information
-abstract class Log implements System.Logger {
-
-    static final String logProp = "java.net.http.HttpClient.log";
-
-    public static final int OFF = 0;
-    public static final int ERRORS = 0x1;
-    public static final int REQUESTS = 0x2;
-    public static final int HEADERS = 0x4;
-    public static final int CONTENT = 0x8;
-    public static final int FRAMES = 0x10;
-    public static final int SSL = 0x20;
-    public static final int TRACE = 0x40;
-    static int logging;
-
-    // Frame types: "control", "data", "window", "all"
-    public static final int CONTROL = 1; // all except DATA and WINDOW_UPDATES
-    public static final int DATA = 2;
-    public static final int WINDOW_UPDATES = 4;
-    public static final int ALL = CONTROL| DATA | WINDOW_UPDATES;
-    static int frametypes;
-
-    static final System.Logger logger;
-
-    static {
-        String s = Utils.getNetProperty(logProp);
-        if (s == null) {
-            logging = OFF;
-        } else {
-            String[] vals = s.split(",");
-            for (String val : vals) {
-                switch (val.toLowerCase(Locale.US)) {
-                    case "errors":
-                        logging |= ERRORS;
-                        break;
-                    case "requests":
-                        logging |= REQUESTS;
-                        break;
-                    case "headers":
-                        logging |= HEADERS;
-                        break;
-                    case "content":
-                        logging |= CONTENT;
-                        break;
-                    case "ssl":
-                        logging |= SSL;
-                        break;
-                    case "trace":
-                        logging |= TRACE;
-                        break;
-                    case "all":
-                        logging |= CONTENT|HEADERS|REQUESTS|FRAMES|ERRORS|TRACE|SSL;
-                        break;
-                }
-                if (val.startsWith("frames")) {
-                    logging |= FRAMES;
-                    String[] types = val.split(":");
-                    if (types.length == 1) {
-                        frametypes = CONTROL | DATA | WINDOW_UPDATES;
-                    } else {
-                        for (String type : types) {
-                            switch (type.toLowerCase()) {
-                                case "control":
-                                    frametypes |= CONTROL;
-                                    break;
-                                case "data":
-                                    frametypes |= DATA;
-                                    break;
-                                case "window":
-                                    frametypes |= WINDOW_UPDATES;
-                                    break;
-                                case "all":
-                                    frametypes = ALL;
-                                    break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        if (logging != OFF) {
-            logger = System.getLogger("java.net.http.HttpClient");
-        } else {
-            logger = null;
-        }
-    }
-
-    static boolean errors() {
-        return (logging & ERRORS) != 0;
-    }
-
-    static boolean requests() {
-        return (logging & REQUESTS) != 0;
-    }
-
-    static boolean headers() {
-        return (logging & HEADERS) != 0;
-    }
-
-    static boolean trace() {
-        return (logging & TRACE) != 0;
-    }
-
-    static boolean ssl() {
-        return (logging & SSL) != 0;
-    }
-
-    static boolean frames() {
-        return (logging & FRAMES) != 0;
-    }
-
-    static void logError(String s, Object... s1) {
-        if (errors())
-            logger.log(Level.INFO, "ERROR: " + s, s1);
-    }
-
-    static void logError(Throwable t) {
-        if (errors()) {
-            String s = Utils.stackTrace(t);
-            logger.log(Level.INFO, "ERROR: " + s);
-        }
-    }
-
-    static void logSSL(String s, Object... s1) {
-        if (ssl())
-            logger.log(Level.INFO, "SSL: " + s, s1);
-    }
-
-    static void logTrace(String s, Object... s1) {
-        if (trace()) {
-            String format = "TRACE: " + s;
-            logger.log(Level.INFO, format, s1);
-        }
-    }
-
-    static void logRequest(String s, Object... s1) {
-        if (requests())
-            logger.log(Level.INFO, "REQUEST: " + s, s1);
-    }
-
-    static void logResponse(String s, Object... s1) {
-        if (requests())
-            logger.log(Level.INFO, "RESPONSE: " + s, s1);
-    }
-
-    static void logHeaders(String s, Object... s1) {
-        if (headers())
-            logger.log(Level.INFO, "HEADERS: " + s, s1);
-    }
-// START HTTP2
-    static boolean loggingFrame(Class<? extends Http2Frame> clazz) {
-        if (frametypes == ALL) {
-            return true;
-        }
-        if (clazz == DataFrame.class) {
-            return (frametypes & DATA) != 0;
-        } else if (clazz == WindowUpdateFrame.class) {
-            return (frametypes & WINDOW_UPDATES) != 0;
-        } else {
-            return (frametypes & CONTROL) != 0;
-        }
-    }
-
-    static void logFrames(Http2Frame f, String direction) {
-        if (frames() && loggingFrame(f.getClass())) {
-            logger.log(Level.INFO, "FRAME: " + direction + ": " + f.toString());
-        }
-    }
-
-    // not instantiable
-    private Log() {}
-
-// END HTTP2
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/MultiExchange.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
-import java.util.concurrent.ExecutionException;
-import java.util.function.BiFunction;
-
-import static java.net.http.Pair.pair;
-
-/**
- * Encapsulates multiple Exchanges belonging to one HttpRequestImpl.
- * - manages filters
- * - retries due to filters.
- * - I/O errors and most other exceptions get returned directly to user
- *
- * Creates a new Exchange for each request/response interaction
- */
-class MultiExchange {
-
-    final HttpRequestImpl request; // the user request
-    final HttpClientImpl client;
-    HttpRequestImpl currentreq; // used for async only
-    Exchange exchange; // the current exchange
-    Exchange previous;
-    int attempts;
-    // Maximum number of times a request will be retried/redirected
-    // for any reason
-
-    final static int DEFAULT_MAX_ATTEMPTS = 5;
-    final static int max_attempts = Utils.getIntegerNetProperty(
-            "java.net.httpclient.redirects.retrylimit", DEFAULT_MAX_ATTEMPTS
-    );
-
-    private final List<HeaderFilter> filters;
-    TimedEvent td;
-    boolean cancelled = false;
-
-    /**
-     * Filter fields. These are attached as required by filters
-     * and only used by the filter implementations. This could be
-     * generalised into Objects that are passed explicitly to the filters
-     * (one per MultiExchange object, and one per Exchange object possibly)
-     */
-    volatile AuthenticationFilter.AuthInfo serverauth, proxyauth;
-    // RedirectHandler
-    volatile int numberOfRedirects = 0;
-
-    /**
-     */
-    MultiExchange(HttpRequestImpl request) {
-        this.exchange = new Exchange(request);
-        this.previous = null;
-        this.request = request;
-        this.currentreq = request;
-        this.attempts = 0;
-        this.client = request.client();
-        this.filters = client.filterChain();
-    }
-
-    public HttpResponseImpl response() throws IOException, InterruptedException {
-        HttpRequestImpl r = request;
-        if (r.timeval() != 0) {
-            // set timer
-            td = new TimedEvent(r.timeval());
-            client.registerTimer(td);
-        }
-        while (attempts < max_attempts) {
-            try {
-                attempts++;
-                Exchange currExchange = getExchange();
-                requestFilters(r);
-                HttpResponseImpl response = currExchange.response();
-                Pair<HttpResponse, HttpRequestImpl> filterResult = responseFilters(response);
-                HttpRequestImpl newreq = filterResult.second;
-                if (newreq == null) {
-                    if (attempts > 1) {
-                        Log.logError("Succeeded on attempt: " + attempts);
-                    }
-                    cancelTimer();
-                    return response;
-                }
-                response.body(HttpResponse.ignoreBody());
-                setExchange(new Exchange(newreq, currExchange.getAccessControlContext() ));
-                r = newreq;
-            } catch (IOException e) {
-                if (cancelled) {
-                    throw new HttpTimeoutException("Request timed out");
-                }
-                throw e;
-            }
-        }
-        cancelTimer();
-        throw new IOException("Retry limit exceeded");
-    }
-
-    private synchronized Exchange getExchange() {
-        return exchange;
-    }
-
-    private synchronized void setExchange(Exchange exchange) {
-        this.exchange = exchange;
-    }
-
-    private void cancelTimer() {
-        if (td != null) {
-            client.cancelTimer(td);
-        }
-    }
-
-    private void requestFilters(HttpRequestImpl r) throws IOException {
-        for (HeaderFilter filter : filters) {
-            filter.request(r);
-        }
-    }
-
-    // Filters are assumed to be non-blocking so the async
-    // versions of these methods just call the blocking ones
-
-    private CompletableFuture<Void> requestFiltersAsync(HttpRequestImpl r) {
-        CompletableFuture<Void> cf = new CompletableFuture<>();
-        try {
-            requestFilters(r);
-            cf.complete(null);
-        } catch(Throwable e) {
-            cf.completeExceptionally(e);
-        }
-        return cf;
-    }
-
-
-    private Pair<HttpResponse,HttpRequestImpl>
-    responseFilters(HttpResponse response) throws IOException
-    {
-        for (HeaderFilter filter : filters) {
-            HttpRequestImpl newreq = filter.response((HttpResponseImpl)response);
-            if (newreq != null) {
-                return pair(null, newreq);
-            }
-        }
-        return pair(response, null);
-    }
-
-    private CompletableFuture<Pair<HttpResponse,HttpRequestImpl>>
-    responseFiltersAsync(HttpResponse response)
-    {
-        CompletableFuture<Pair<HttpResponse,HttpRequestImpl>> cf = new CompletableFuture<>();
-        try {
-            Pair<HttpResponse,HttpRequestImpl> n = responseFilters(response); // assumed to be fast
-            cf.complete(n);
-        } catch (Throwable e) {
-            cf.completeExceptionally(e);
-        }
-        return cf;
-    }
-
-    public void cancel() {
-        cancelled = true;
-        getExchange().cancel();
-    }
-
-    public CompletableFuture<HttpResponseImpl> responseAsync(Void v) {
-        CompletableFuture<HttpResponseImpl> cf;
-        if (++attempts > max_attempts) {
-            cf = CompletableFuture.failedFuture(new IOException("Too many retries"));
-        } else {
-            if (currentreq.timeval() != 0) {
-                // set timer
-                td = new TimedEvent(currentreq.timeval());
-                client.registerTimer(td);
-            }
-            Exchange exch = getExchange();
-            cf = requestFiltersAsync(currentreq)
-                .thenCompose(exch::responseAsync)
-                .thenCompose(this::responseFiltersAsync)
-                .thenCompose((Pair<HttpResponse,HttpRequestImpl> pair) -> {
-                    HttpResponseImpl resp = (HttpResponseImpl)pair.first;
-                    if (resp != null) {
-                        if (attempts > 1) {
-                            Log.logError("Succeeded on attempt: " + attempts);
-                        }
-                        return CompletableFuture.completedFuture(resp);
-                    } else {
-                        currentreq = pair.second;
-                        Exchange previous = exch;
-                        setExchange(new Exchange(currentreq,
-                                                 currentreq.getAccessControlContext()));
-                        //reads body off previous, and then waits for next response
-                        return previous
-                                .responseBodyAsync(HttpResponse.ignoreBody())
-                                .thenCompose(this::responseAsync);
-                    }
-                })
-            .handle((BiFunction<HttpResponse, Throwable, Pair<HttpResponse, Throwable>>) Pair::new)
-            .thenCompose((Pair<HttpResponse,Throwable> obj) -> {
-                HttpResponseImpl response = (HttpResponseImpl)obj.first;
-                if (response != null) {
-                    return CompletableFuture.completedFuture(response);
-                }
-                // all exceptions thrown are handled here
-                CompletableFuture<HttpResponseImpl> error = getExceptionalCF(obj.second);
-                if (error == null) {
-                    cancelTimer();
-                    return responseAsync(null);
-                } else {
-                    return error;
-                }
-            });
-        }
-        return cf;
-    }
-
-    /**
-     * Take a Throwable and return a suitable CompletableFuture that is
-     * completed exceptionally.
-     */
-    private CompletableFuture<HttpResponseImpl> getExceptionalCF(Throwable t) {
-        if ((t instanceof CompletionException) || (t instanceof ExecutionException)) {
-            if (t.getCause() != null) {
-                t = t.getCause();
-            }
-        }
-        if (cancelled && t instanceof IOException) {
-            t = new HttpTimeoutException("request timed out");
-        }
-        return CompletableFuture.failedFuture(t);
-    }
-
-    <T> T responseBody(HttpResponse.BodyProcessor<T> processor) {
-        return getExchange().responseBody(processor);
-    }
-
-    <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
-        return getExchange().responseBodyAsync(processor);
-    }
-
-    class TimedEvent extends TimeoutEvent {
-        TimedEvent(long timeval) {
-            super(timeval);
-        }
-        @Override
-        public void handle() {
-            cancel();
-        }
-
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/OutgoingHeaders.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-/**
- * Contains all parameters for outgoing headers. Is converted to
- * HeadersFrame and ContinuationFrames by Http2Connection.
- */
-class OutgoingHeaders extends Http2Frame {
-
-    int streamDependency;
-    int weight;
-    boolean exclusive;
-    Stream stream;
-
-    public static final int PRIORITY = 0x20;
-
-    HttpHeaders user, system;
-
-    OutgoingHeaders(HttpHeaders hdrs1, HttpHeaders hdrs2, Stream stream) {
-        this.user = hdrs2;
-        this.system = hdrs1;
-        this.stream = stream;
-    }
-
-    public void setPriority(int streamDependency, boolean exclusive, int weight) {
-        this.streamDependency = streamDependency;
-        this.exclusive = exclusive;
-        this.weight = weight;
-        this.flags |= PRIORITY;
-    }
-
-    public int getStreamDependency() {
-        return streamDependency;
-    }
-
-    public int getWeight() {
-        return weight;
-    }
-
-    public boolean getExclusive() {
-        return exclusive;
-    }
-
-    public Stream getStream() {
-        return stream;
-    }
-
-    public HttpHeaders getUserHeaders() {
-        return user;
-    }
-
-    public HttpHeaders getSystemHeaders() {
-        return system;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        throw new UnsupportedOperationException("Not supported.");
-    }
-
-    @Override
-    void computeLength() {
-        //To change body of generated methods, choose Tools | Templates.
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Pair.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-/**
- * A simple paired value class
- */
-final class Pair<T, U> {
-
-    Pair(T first, U second) {
-        this.second = second;
-        this.first = first;
-    }
-
-    final T first;
-    final U second;
-
-    // Because 'pair()' is shorter than 'new Pair<>()'.
-    // Sometimes this difference might be very significant (especially in a
-    // 80-ish characters boundary). Sorry diamond operator.
-    static <T, U> Pair<T, U> pair(T first, U second) {
-        return new Pair<>(first, second);
-    }
-
-    @Override
-    public String toString() {
-        return "(" + first + ", " + second + ")";
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PingFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class PingFrame extends Http2Frame {
-
-    PingFrame() {
-        type = TYPE;
-    }
-
-    byte[] data;
-
-    public final static int TYPE = 0x6;
-
-    // Flags
-    public static final int ACK = 0x1;
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-        case ACK:
-            return "ACK";
-        }
-        return super.flagAsString(flag);
-    }
-
-    public void setData(byte[] data) {
-        if (data.length != 8) {
-            throw new IllegalArgumentException("Ping data not 8 bytes");
-        }
-        this.data = data;
-    }
-
-    public byte[] getData() {
-        return data;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if (length != 8) {
-            throw new IOException("Invalid Ping frame");
-        }
-        data = bc.getBytes(8);
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        if (data == null) {
-            data = new byte[] {0, 0, 0, 0, 0 ,0, 0, 0};
-        }
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(8);
-        buf.put(data);
-    }
-
-    @Override
-    void computeLength() {
-        length = 8;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PlainHttpConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.net.StandardSocketOptions;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.Consumer;
-
-/**
- * Plain raw TCP connection direct to destination. 2 modes
- * 1) Blocking used by http/1. In this case the connect is actually non
- *    blocking but the request is sent blocking. The first byte of a response
- *    is received non-blocking and the remainder of the response is received
- *    blocking
- * 2) Non-blocking. In this case (for http/2) the connection is actually opened
- *    blocking but all reads and writes are done non-blocking under the
- *    control of a Http2Connection object.
- */
-class PlainHttpConnection extends HttpConnection implements AsyncConnection {
-
-    protected SocketChannel chan;
-    private volatile boolean connected;
-    private boolean closed;
-    Consumer<ByteBuffer> asyncReceiver;
-    Consumer<Throwable> errorReceiver;
-    Queue<ByteBuffer> asyncOutputQ;
-    final Object reading = new Object();
-    final Object writing = new Object();
-
-    @Override
-    public void startReading() {
-        try {
-            client.registerEvent(new ReadEvent());
-        } catch (IOException e) {
-            shutdown();
-        }
-    }
-
-    class ConnectEvent extends AsyncEvent {
-        CompletableFuture<Void> cf;
-
-        ConnectEvent(CompletableFuture<Void> cf) {
-            super(AsyncEvent.BLOCKING);
-            this.cf = cf;
-        }
-
-        @Override
-        public SelectableChannel channel() {
-            return chan;
-        }
-
-        @Override
-        public int interestOps() {
-            return SelectionKey.OP_CONNECT;
-        }
-
-        @Override
-        public void handle() {
-            try {
-                chan.finishConnect();
-            } catch (IOException e) {
-                cf.completeExceptionally(e);
-            }
-            connected = true;
-            cf.complete(null);
-        }
-
-        @Override
-        public void abort() {
-            close();
-        }
-    }
-
-    @Override
-    public CompletableFuture<Void> connectAsync() {
-        CompletableFuture<Void> plainFuture = new CompletableFuture<>();
-        try {
-            chan.configureBlocking(false);
-            chan.connect(address);
-            client.registerEvent(new ConnectEvent(plainFuture));
-        } catch (IOException e) {
-            plainFuture.completeExceptionally(e);
-        }
-        return plainFuture;
-    }
-
-    @Override
-    public void connect() throws IOException {
-        chan.connect(address);
-        connected = true;
-    }
-
-    @Override
-    SocketChannel channel() {
-        return chan;
-    }
-
-    PlainHttpConnection(InetSocketAddress addr, HttpClientImpl client) {
-        super(addr, client);
-        try {
-            this.chan = SocketChannel.open();
-            int bufsize = client.getReceiveBufferSize();
-            chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize);
-            chan.setOption(StandardSocketOptions.TCP_NODELAY, true);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    @Override
-    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
-        if (mode != Mode.ASYNC)
-            return chan.write(buffers, start, number);
-        // async
-        synchronized(writing) {
-            int qlen = asyncOutputQ.size();
-            ByteBuffer[] bufs = Utils.reduce(buffers, start, number);
-            long n = Utils.remaining(bufs);
-            asyncOutputQ.putAll(bufs);
-            if (qlen == 0)
-                asyncOutput();
-            return n;
-        }
-    }
-
-    ByteBuffer asyncBuffer = null;
-
-    void asyncOutput() {
-        synchronized (writing) {
-            try {
-                while (true) {
-                    if (asyncBuffer == null) {
-                        asyncBuffer = asyncOutputQ.poll();
-                        if (asyncBuffer == null) {
-                            return;
-                        }
-                    }
-                    if (!asyncBuffer.hasRemaining()) {
-                        asyncBuffer = null;
-                        continue;
-                    }
-                    int n = chan.write(asyncBuffer);
-                    //System.err.printf("Written %d bytes to chan\n", n);
-                    if (n == 0) {
-                        client.registerEvent(new WriteEvent());
-                        return;
-                    }
-                }
-            } catch (IOException e) {
-                shutdown();
-            }
-        }
-    }
-
-    @Override
-    long write(ByteBuffer buffer) throws IOException {
-        if (mode != Mode.ASYNC)
-            return chan.write(buffer);
-        // async
-        synchronized(writing) {
-            int qlen = asyncOutputQ.size();
-            long n = buffer.remaining();
-            asyncOutputQ.put(buffer);
-            if (qlen == 0)
-                asyncOutput();
-            return n;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "PlainHttpConnection: " + super.toString();
-    }
-
-    /**
-     * Close this connection
-     */
-    @Override
-    public synchronized void close() {
-        if (closed)
-            return;
-        closed = true;
-        try {
-            Log.logError("Closing: " + toString());
-            //System.out.println("Closing: " + this);
-            chan.close();
-        } catch (IOException e) {}
-    }
-
-    @Override
-    protected ByteBuffer readImpl(int length) throws IOException {
-        ByteBuffer buf = getBuffer(); // TODO not using length
-        int n = chan.read(buf);
-        if (n == -1) {
-            return null;
-        }
-        buf.flip();
-        String s = "Receive (" + n + " bytes) ";
-        //debugPrint(s, buf);
-        return buf;
-    }
-
-    void shutdown() {
-        close();
-        errorReceiver.accept(new IOException("Connection aborted"));
-    }
-
-    void asyncRead() {
-        synchronized (reading) {
-            try {
-                while (true) {
-                    ByteBuffer buf = getBuffer();
-                    int n = chan.read(buf);
-                    //System.err.printf("Read %d bytes from chan\n", n);
-                    if (n == -1) {
-                        throw new IOException();
-                    }
-                    if (n == 0) {
-                        returnBuffer(buf);
-                        return;
-                    }
-                    buf.flip();
-                    asyncReceiver.accept(buf);
-                }
-            } catch (IOException e) {
-                shutdown();
-            }
-        }
-    }
-
-    @Override
-    protected int readImpl(ByteBuffer buf) throws IOException {
-        int mark = buf.position();
-        int n;
-        // FIXME: this hack works in conjunction with the corresponding change
-        // in java.net.http.RawChannel.registerEvent
-        if ((n = buffer.remaining()) != 0) {
-            buf.put(buffer);
-        } else {
-            n = chan.read(buf);
-        }
-        if (n == -1) {
-            return -1;
-        }
-        Utils.flipToMark(buf, mark);
-        String s = "Receive (" + n + " bytes) ";
-        //debugPrint(s, buf);
-        return n;
-    }
-
-    @Override
-    ConnectionPool.CacheKey cacheKey() {
-        return new ConnectionPool.CacheKey(address, null);
-    }
-
-    @Override
-    synchronized boolean connected() {
-        return connected;
-    }
-
-    // used for all output in HTTP/2
-    class WriteEvent extends AsyncEvent {
-        WriteEvent() {
-            super(0);
-        }
-
-        @Override
-        public SelectableChannel channel() {
-            return chan;
-        }
-
-        @Override
-        public int interestOps() {
-            return SelectionKey.OP_WRITE;
-        }
-
-        @Override
-        public void handle() {
-            asyncOutput();
-        }
-
-        @Override
-        public void abort() {
-            shutdown();
-        }
-    }
-
-    // used for all input in HTTP/2
-    class ReadEvent extends AsyncEvent {
-        ReadEvent() {
-            super(AsyncEvent.REPEATING); // && !BLOCKING
-        }
-
-        @Override
-        public SelectableChannel channel() {
-            return chan;
-        }
-
-        @Override
-        public int interestOps() {
-            return SelectionKey.OP_READ;
-        }
-
-        @Override
-        public void handle() {
-            asyncRead();
-        }
-
-        @Override
-        public void abort() {
-            shutdown();
-        }
-
-    }
-
-    // used in blocking channels only
-    class ReceiveResponseEvent extends AsyncEvent {
-        CompletableFuture<Void> cf;
-
-        ReceiveResponseEvent(CompletableFuture<Void> cf) {
-            super(AsyncEvent.BLOCKING);
-            this.cf = cf;
-        }
-        @Override
-        public SelectableChannel channel() {
-            return chan;
-        }
-
-        @Override
-        public void handle() {
-            cf.complete(null);
-        }
-
-        @Override
-        public int interestOps() {
-            return SelectionKey.OP_READ;
-        }
-
-        @Override
-        public void abort() {
-            close();
-        }
-    }
-
-    @Override
-    boolean isSecure() {
-        return false;
-    }
-
-    @Override
-    boolean isProxied() {
-        return false;
-    }
-
-    @Override
-    public synchronized void setAsyncCallbacks(Consumer<ByteBuffer> asyncReceiver,
-            Consumer<Throwable> errorReceiver) {
-        this.asyncReceiver = asyncReceiver;
-        this.errorReceiver = errorReceiver;
-        asyncOutputQ = new Queue<>();
-        asyncOutputQ.registerPutCallback(this::asyncOutput);
-    }
-
-    @Override
-    CompletableFuture<Void> whenReceivingResponse() {
-        CompletableFuture<Void> cf = new CompletableFuture<>();
-        try {
-            client.registerEvent(new ReceiveResponseEvent(cf));
-        } catch (IOException e) {
-            cf.completeExceptionally(e);
-        }
-        return cf;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PlainProxyConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-
-class PlainProxyConnection extends PlainHttpConnection {
-
-    PlainProxyConnection(InetSocketAddress proxy, HttpClientImpl client) {
-        super(proxy, client);
-    }
-
-    @Override
-    ConnectionPool.CacheKey cacheKey() {
-        return new ConnectionPool.CacheKey(null, address);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PlainTunnelingConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.security.AccessControlContext;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * A plain text socket tunnel through a proxy. Uses "CONNECT" but does not
- * encrypt. Used by WebSockets. Subclassed in SSLTunnelConnection for encryption.
- */
-class PlainTunnelingConnection extends HttpConnection {
-
-    final PlainHttpConnection delegate;
-    protected final InetSocketAddress proxyAddr;
-    private volatile boolean connected;
-    private final AccessControlContext acc;
-
-    @Override
-    public CompletableFuture<Void> connectAsync() {
-        return delegate.connectAsync()
-            .thenCompose((Void v) -> {
-                HttpRequestImpl req = new HttpRequestImpl(client, "CONNECT", address);
-                Exchange connectExchange = new Exchange(req, acc);
-                return connectExchange
-                    .responseAsyncImpl(delegate)
-                    .thenCompose((HttpResponse r) -> {
-                        CompletableFuture<Void> cf = new CompletableFuture<>();
-                        if (r.statusCode() != 200) {
-                            cf.completeExceptionally(new IOException("Tunnel failed"));
-                        } else {
-                            connected = true;
-                            cf.complete(null);
-                        }
-                        return cf;
-                    });
-            });
-    }
-
-    @Override
-    public void connect() throws IOException, InterruptedException {
-        delegate.connect();
-        HttpRequestImpl req = new HttpRequestImpl(client, "CONNECT", address);
-        Exchange connectExchange = new Exchange(req, acc);
-        HttpResponse r = connectExchange.responseImpl(delegate);
-        if (r.statusCode() != 200) {
-            throw new IOException("Tunnel failed");
-        }
-        connected = true;
-    }
-
-    @Override
-    boolean connected() {
-        return connected;
-    }
-
-    protected PlainTunnelingConnection(InetSocketAddress addr,
-                                       InetSocketAddress proxy,
-                                       HttpClientImpl client,
-                                       AccessControlContext acc) {
-        super(addr, client);
-        this.proxyAddr = proxy;
-        this.acc = acc;
-        delegate = new PlainHttpConnection(proxy, client);
-    }
-
-    @Override
-    SocketChannel channel() {
-        return delegate.channel();
-    }
-
-    @Override
-    ConnectionPool.CacheKey cacheKey() {
-        return new ConnectionPool.CacheKey(null, proxyAddr);
-    }
-
-    @Override
-    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
-        return delegate.write(buffers, start, number);
-    }
-
-    @Override
-    long write(ByteBuffer buffer) throws IOException {
-        return delegate.write(buffer);
-    }
-
-    @Override
-    public void close() {
-        delegate.close();
-        connected = false;
-    }
-
-    @Override
-    protected ByteBuffer readImpl(int length) throws IOException {
-        return delegate.readImpl(length);
-    }
-
-    @Override
-    CompletableFuture<Void> whenReceivingResponse() {
-        return delegate.whenReceivingResponse();
-    }
-
-    @Override
-    protected int readImpl(ByteBuffer buffer) throws IOException {
-        return delegate.readImpl(buffer);
-    }
-
-    @Override
-    boolean isSecure() {
-        return false;
-    }
-
-    @Override
-    boolean isProxied() {
-        return true;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PriorityFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class PriorityFrame extends Http2Frame {
-
-    int streamDependency;
-    int weight;
-    boolean exclusive;
-
-    public final static int TYPE = 0x2;
-
-    PriorityFrame() {
-        type = TYPE;
-    }
-
-    public PriorityFrame(int streamDependency, boolean exclusive, int weight) {
-        this.streamDependency = streamDependency;
-        this.exclusive = exclusive;
-        this.weight = weight;
-        this.type = TYPE;
-    }
-
-    int streamDependency() {
-        return streamDependency;
-    }
-
-    int weight() {
-        return weight;
-    }
-
-    boolean exclusive() {
-        return exclusive;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        int x = bc.getInt();
-        exclusive = (x & 0x80000000) != 0;
-        streamDependency = x & 0x7fffffff;
-        weight = bc.getByte();
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(5);
-        int x = exclusive ? (1 << 31) + streamDependency : streamDependency;
-        buf.putInt(x);
-        buf.put((byte)weight);
-    }
-
-    @Override
-    void computeLength() {
-        length = 5;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PushPromiseFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class PushPromiseFrame extends HeaderFrame {
-
-    int padLength;
-    int promisedStream;
-
-    PushPromiseFrame() {
-        type = TYPE;
-    }
-
-    public static final int TYPE = 0x5;
-
-    // Flags
-    public static final int END_HEADERS = 0x4;
-    public static final int PADDED = 0x8;
-
-    @Override
-    public String toString() {
-        return super.toString() + " promisedStreamid: " + promisedStream
-                + " headerLength: " + headerLength;
-    }
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-        case PADDED:
-            return "PADDED";
-        case END_HEADERS:
-            return "END_HEADERS";
-        }
-        return super.flagAsString(flag);
-    }
-
-    public void setPadLength(int padLength) {
-        this.padLength = padLength;
-        flags |= PADDED;
-    }
-
-    public void setPromisedStream(int stream) {
-        this.promisedStream = stream;
-    }
-
-    public int getPromisedStream() {
-        return promisedStream;
-    }
-
-    /**
-     */
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if ((flags & PADDED) != 0) {
-            padLength = bc.getByte();
-            headerLength = length - (padLength + 5);
-        } else
-            headerLength = length - 4;
-
-        promisedStream = bc.getInt() & 0x7fffffff;
-        headerBlocks = bc.getBuffers(headerLength);
-    }
-
-    @Override
-    void computeLength() {
-        int len = 0;
-        if ((flags & PADDED) != 0) {
-            len += (1 + padLength);
-        }
-        len += (4 + headerLength);
-        this.length = len;
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(length);
-        if ((flags & PADDED) != 0) {
-            buf.put((byte)padLength);
-        }
-        buf.putInt(promisedStream);
-        for (int i=0; i<headerBlocks.length; i++) {
-            bg.addByteBuffer(headerBlocks[i]);
-        }
-        if ((flags & PADDED) != 0) {
-            bg.addPadding(padLength);
-        }
-    }
-
-    @Override
-    public boolean endHeaders() {
-        return getFlag(END_HEADERS);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Queue.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.Closeable;
-import java.io.IOException;
-import java.util.LinkedList;
-
-// Each stream has one of these for input. Each Http2Connection has one
-// for output. Can be used blocking or asynchronously.
-
-class Queue<T> implements Closeable {
-
-    private final LinkedList<T> q = new LinkedList<>();
-    private volatile boolean closed = false;
-    private Runnable callback;
-    private boolean forceCallback;
-    private int waiters; // true if someone waiting
-
-    synchronized void putAll(T[] objs) throws IOException {
-        if (closed) {
-            throw new IOException("stream closed");
-        }
-        boolean wasEmpty = q.isEmpty();
-
-        for (T obj : objs) {
-            q.add(obj);
-        }
-
-        if (waiters > 0)
-            notifyAll();
-
-        if (wasEmpty || forceCallback) {
-            forceCallback = false;
-            if (callback != null) {
-                callback.run();
-            }
-        }
-    }
-
-    synchronized int size() {
-        return q.size();
-    }
-
-    synchronized void put(T obj) throws IOException {
-        if (closed) {
-            throw new IOException("stream closed");
-        }
-
-        q.add(obj);
-        if (waiters > 0)
-            notifyAll();
-
-        if (q.size() == 1 || forceCallback) {
-            forceCallback = false;
-            if (callback != null) {
-                callback.run();
-            }
-        }
-    }
-
-    /**
-     * callback is invoked any time put is called where
-     * the Queue was empty.
-     */
-    synchronized void registerPutCallback(Runnable callback) {
-        this.callback = callback;
-        if (callback != null && q.size() > 0)
-            callback.run();
-    }
-
-    @Override
-    public synchronized void close() {
-        closed = true;
-        notifyAll();
-    }
-
-    synchronized T take() throws IOException {
-        if (closed) {
-            throw new IOException("stream closed");
-        }
-        try {
-            while (q.size() == 0) {
-                waiters++;
-                wait();
-                if (closed)
-                    throw new IOException("Queue closed");
-                waiters--;
-            }
-            return q.removeFirst();
-        } catch (InterruptedException ex) {
-            throw new IOException(ex);
-        }
-    }
-
-    public synchronized T poll() throws IOException {
-        if (closed)
-            throw new IOException("stream closed");
-
-        if (q.isEmpty())
-            return null;
-        T res = q.removeFirst();
-        return res;
-    }
-
-    public synchronized T[] pollAll(T[] type) throws IOException {
-        T[] ret = q.toArray(type);
-        q.clear();
-        return ret;
-    }
-
-    public synchronized void pushback(T v) {
-        forceCallback = true;
-        q.addFirst(v);
-    }
-
-    public synchronized void pushbackAll(T[] v) {
-        forceCallback = true;
-        for (int i=v.length-1; i>=0; i--) {
-            q.addFirst(v[i]);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-/*
- * I/O abstraction used to implement WebSocket.
- */
-interface RawChannel {
-
-    interface RawEvent {
-
-        /*
-         * Must return the selector interest op flags.
-         */
-        int interestOps();
-
-        /*
-         * Called when event occurs.
-         */
-        void handle();
-    }
-
-    /*
-     * Register given event whose callback will be called once only.
-     * (i.e. register new event for each callback)
-     */
-    void registerEvent(RawEvent event) throws IOException;
-
-    int read(ByteBuffer dst) throws IOException;
-
-    long write(ByteBuffer[] src, int offset, int len) throws IOException;
-
-    boolean isOpen();
-
-    void close() throws IOException;
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/RawChannelImpl.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-
-/*
- * Each RawChannel corresponds to a TCP connection (SocketChannel) but is
- * connected to a Selector and an ExecutorService for invoking the send and
- * receive callbacks. Also includes SSL processing.
- */
-final class RawChannelImpl implements RawChannel {
-
-    private final HttpClientImpl client;
-    private final HttpConnection connection;
-
-    RawChannelImpl(HttpClientImpl client, HttpConnection connection)
-            throws IOException {
-        this.client = client;
-        this.connection = connection;
-        SocketChannel chan = connection.channel();
-        client.cancelRegistration(chan);
-        chan.configureBlocking(false);
-    }
-
-    private class NonBlockingRawAsyncEvent extends AsyncEvent {
-
-        private final RawEvent re;
-
-        NonBlockingRawAsyncEvent(RawEvent re) {
-            super(0); // !BLOCKING & !REPEATING
-            this.re = re;
-        }
-
-        @Override
-        public SelectableChannel channel() {
-            return connection.channel();
-        }
-
-        @Override
-        public int interestOps() {
-            return re.interestOps();
-        }
-
-        @Override
-        public void handle() {
-            re.handle();
-        }
-
-        @Override
-        public void abort() { }
-    }
-
-    @Override
-    public void registerEvent(RawEvent event) throws IOException {
-        if ((event.interestOps() & SelectionKey.OP_READ) != 0
-                && connection.buffer.hasRemaining()) {
-            // FIXME: a hack to deal with leftovers from previous reads into an
-            // internal buffer (works in conjunction with change in
-            // java.net.http.PlainHttpConnection.readImpl(java.nio.ByteBuffer)
-            connection.channel().configureBlocking(false);
-            event.handle();
-        } else {
-            client.registerEvent(new NonBlockingRawAsyncEvent(event));
-        }
-    }
-
-    @Override
-    public int read(ByteBuffer dst) throws IOException {
-        assert !connection.channel().isBlocking();
-        return connection.read(dst);
-    }
-
-    @Override
-    public long write(ByteBuffer[] src, int offset, int len) throws IOException {
-        return connection.write(src, offset, len);
-    }
-
-    @Override
-    public boolean isOpen() {
-        return connection.isOpen();
-    }
-
-    @Override
-    public void close() throws IOException {
-        connection.close();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/RedirectFilter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.URI;
-
-class RedirectFilter implements HeaderFilter {
-
-    HttpRequestImpl requestImpl;
-    HttpRequest request;
-    HttpClientImpl client;
-    HttpClient.Redirect policy;
-    String method;
-    final static int DEFAULT_MAX_REDIRECTS = 5;
-    URI uri;
-
-    final static int max_redirects = Utils.getIntegerNetProperty(
-            "java.net.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS
-    );
-
-    @Override
-    public void request(HttpRequestImpl r) throws IOException {
-        this.request = r;
-        this.policy = request.followRedirects();
-        this.client = r.getClient();
-        this.method = r.method();
-        this.requestImpl = r;
-        this.uri = r.uri();
-    }
-
-    @Override
-    public HttpRequestImpl response(HttpResponseImpl r) throws IOException {
-        return handleResponse(r);
-    }
-
-    /**
-     * checks to see if new request needed and returns it.
-     * Null means response is ok to return to user.
-     */
-    private HttpRequestImpl handleResponse(HttpResponseImpl r) {
-        int rcode = r.statusCode();
-        if (rcode == 200 || policy == HttpClient.Redirect.NEVER) {
-            return null;
-        }
-        if (rcode >= 300 && rcode <= 399) {
-            URI redir = getRedirectedURI(r.headers());
-            if (canRedirect(r) && ++r.request.exchange.numberOfRedirects < max_redirects) {
-                //System.out.println("Redirecting to: " + redir);
-                return new HttpRequestImpl(redir, request, client, method, requestImpl);
-            } else {
-                //System.out.println("Redirect: giving up");
-                return null;
-            }
-        }
-        return null;
-    }
-
-    private URI getRedirectedURI(HttpHeaders headers) {
-        URI redirectedURI;
-        String ss = headers.firstValue("Location").orElse("Not present");
-        redirectedURI = headers.firstValue("Location")
-                .map((s) -> URI.create(s))
-                .orElseThrow(() -> new UncheckedIOException(
-                        new IOException("Invalid redirection")));
-
-        // redirect could be relative to original URL, but if not
-        // then redirect is used.
-        redirectedURI = uri.resolve(redirectedURI);
-        return redirectedURI;
-    }
-
-    private boolean canRedirect(HttpResponse r) {
-        return requestImpl.followRedirectsImpl().redirect(r);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ResetFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class ResetFrame extends ErrorFrame {
-
-    public final static int TYPE = 0x3;
-
-    // See ErrorFrame for error values
-
-    ResetFrame() {
-        type = TYPE;
-    }
-
-    public ResetFrame(int errorCode) {
-        this.errorCode = errorCode;
-        this.type = TYPE;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        errorCode = bc.getInt();
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(4);
-        buf.putInt(errorCode);
-    }
-
-    @Override
-    void computeLength() {
-        length = 4;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ResponseContent.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,325 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-/**
- * Implements chunked/fixed transfer encodings of HTTP/1.1 responses.
- */
-class ResponseContent {
-
-    final HttpResponse.BodyProcessor<?> userProcessor;
-    final HttpResponse.BodyProcessor<?> pusher;
-    final HttpConnection connection;
-    final int contentLength;
-    ByteBuffer buffer;
-    ByteBuffer lastBufferUsed;
-    final ResponseHeaders headers;
-    final Http1Response.FlowController flowController;
-
-    ResponseContent(HttpConnection connection,
-                    int contentLength,
-                    ResponseHeaders h,
-                    HttpResponse.BodyProcessor<?> userProcessor,
-                    Http1Response.FlowController flowController) {
-        this.userProcessor = userProcessor;
-        this.pusher = (HttpResponse.BodyProcessor)userProcessor;
-        this.connection = connection;
-        this.contentLength = contentLength;
-        this.headers = h;
-        this.flowController = flowController;
-    }
-
-    static final int LF = 10;
-    static final int CR = 13;
-    static final int SP = 0x20;
-    static final int BUF_SIZE = 1024;
-
-    boolean chunkedContent, chunkedContentInitialized;
-
-    private boolean contentChunked() throws IOException {
-        if (chunkedContentInitialized) {
-            return chunkedContent;
-        }
-        if (contentLength == -1) {
-            String tc = headers.firstValue("Transfer-Encoding")
-                               .orElse("");
-            if (!tc.equals("")) {
-                if (tc.equalsIgnoreCase("chunked")) {
-                    chunkedContent = true;
-                } else {
-                    throw new IOException("invalid content");
-                }
-            } else {
-                chunkedContent = false;
-            }
-        }
-        chunkedContentInitialized = true;
-        return chunkedContent;
-    }
-
-    /**
-     * Entry point for pusher. b is an initial ByteBuffer that may
-     * have some data in it. When this method returns, the body
-     * has been fully processed.
-     */
-    void pushBody(ByteBuffer b) throws IOException {
-        // TODO: check status
-        if (contentChunked()) {
-            pushBodyChunked(b);
-        } else {
-            pushBodyFixed(b);
-        }
-    }
-
-    // reads and returns chunklen. Position of chunkbuf is first byte
-    // of chunk on return. chunklen includes the CR LF at end of chunk
-    int readChunkLen() throws IOException {
-        chunklen = 0;
-        boolean cr = false;
-        while (true) {
-            getHunk();
-            int c = chunkbuf.get();
-            if (cr) {
-                if (c == LF) {
-                    return chunklen + 2;
-                } else {
-                    throw new IOException("invalid chunk header");
-                }
-            }
-            if (c == CR) {
-                cr = true;
-            } else {
-                int digit = toDigit(c);
-                chunklen = chunklen * 16 + digit;
-            }
-        }
-    }
-
-    int chunklen = -1;      // number of bytes in chunk (fixed)
-    int bytesremaining;     // number of bytes in chunk left to be read incl CRLF
-    int bytesread;
-    ByteBuffer chunkbuf;    // initialise
-
-    // make sure we have at least 1 byte to look at
-    private void getHunk() throws IOException {
-        while (chunkbuf == null || !chunkbuf.hasRemaining()) {
-
-            if (chunkbuf != null) {
-                connection.returnBuffer(chunkbuf);
-            }
-            chunkbuf = connection.read();
-        }
-    }
-
-    private void consumeBytes(int n) throws IOException {
-        getHunk();
-        while (n > 0) {
-            int e = Math.min(chunkbuf.remaining(), n);
-            chunkbuf.position(chunkbuf.position() + e);
-            n -= e;
-            if (n > 0)
-                getHunk();
-        }
-    }
-
-    /**
-     * Returns a ByteBuffer containing a chunk of data or a "hunk" of data
-     * (a chunk of a chunk if the chunk size is larger than our ByteBuffers).
-     */
-    ByteBuffer readChunkedBuffer() throws IOException {
-        if (chunklen == -1) {
-            // new chunk
-            bytesremaining = readChunkLen();
-            chunklen = bytesremaining - 2;
-            if (chunklen == 0) {
-                consumeBytes(2);
-                return null;
-            }
-        }
-
-        getHunk();
-        bytesread = chunkbuf.remaining();
-        ByteBuffer returnBuffer;
-
-        /**
-         * Cases. Always at least one byte is read by getHunk()
-         *
-         * 1) one read contains exactly 1 chunk. Strip off CRLF and pass buffer on
-         * 2) one read contains a hunk. If at end of chunk, consume CRLF.Pass buffer up.
-         * 3) read contains rest of chunk and more data. Copy buffer.
-         */
-        if (bytesread == bytesremaining) {
-            // common case: 1 read = 1 chunk (or final hunk of chunk)
-            chunkbuf.limit(chunkbuf.limit() - 2); // remove trailing CRLF
-            bytesremaining = 0;
-            returnBuffer = chunkbuf;
-            chunkbuf = null;
-            chunklen = -1;
-        } else if (bytesread < bytesremaining) {
-            // read a hunk, maybe including CR or LF or both
-            bytesremaining -= bytesread;
-            if (bytesremaining <= 2) {
-                // remove any trailing CR LF already read, and then read the rest
-                chunkbuf.limit(chunkbuf.limit() - (2 - bytesremaining));
-                consumeBytes(bytesremaining);
-                chunklen = -1;
-            }
-            returnBuffer = chunkbuf;
-            chunkbuf = null;
-        } else {
-            // bytesread > bytesremaining
-            returnBuffer = splitChunkedBuffer(bytesremaining-2);
-            bytesremaining = 0;
-            chunklen = -1;
-            consumeBytes(2);
-        }
-        return returnBuffer;
-    }
-
-    ByteBuffer initialBuffer;
-    int fixedBytesReturned;
-
-    ByteBuffer getResidue() {
-        return lastBufferUsed;
-    }
-
-    private void compactBuffer(ByteBuffer buf) {
-        buf.compact()
-           .flip();
-    }
-
-    /**
-     * Copies inbuf (numBytes from its position) to new buffer. The returned
-     * buffer's position is zero and limit is at end (numBytes)
-     */
-    private ByteBuffer copyBuffer(ByteBuffer inbuf, int numBytes) {
-        ByteBuffer b1 = connection.getBuffer();
-        assert b1.remaining() >= numBytes;
-        byte[] b = b1.array();
-        inbuf.get(b, 0, numBytes);
-        b1.limit(numBytes);
-        return b1;
-    }
-
-    /**
-     * Split numBytes of data out of chunkbuf from the remainder,
-     * copying whichever part is smaller. chunkbuf points to second part
-     * of buffer on return. The returned buffer is the data from position
-     * to position + numBytes. Both buffers positions are reset so same
-     * data can be re-read.
-     */
-    private ByteBuffer splitChunkedBuffer(int numBytes) {
-        ByteBuffer newbuf = connection.getBuffer();
-        byte[] b = newbuf.array();
-        int midpoint = chunkbuf.position() + numBytes;
-        int remainder = chunkbuf.limit() - midpoint;
-
-        if (numBytes < remainder) {
-            // copy first part of chunkbuf to new buf
-            chunkbuf.get(b, 0, numBytes);
-            newbuf.limit(numBytes);
-            return newbuf;
-        } else {
-            // copy remainder of chunkbuf to newbuf and make newbuf chunkbuf
-            chunkbuf.mark();
-            chunkbuf.position(midpoint);
-            chunkbuf.get(b, 0, remainder);
-            chunkbuf.reset();
-            chunkbuf.limit(midpoint);
-            newbuf.limit(remainder);
-            newbuf.position(0);
-            ByteBuffer tmp = chunkbuf;
-            chunkbuf = newbuf;
-            return tmp;
-        }
-    }
-
-    private void pushBodyChunked(ByteBuffer b) throws IOException {
-        chunkbuf = b;
-        while (true) {
-            ByteBuffer b1 = readChunkedBuffer();
-            if (b1 != null) {
-                if (b1.hasRemaining()) {
-                    request(1); // wait till we can send
-                    pusher.onResponseBodyChunk(b1);
-                    lastBufferUsed = b1;
-                }
-            } else {
-                return;
-            }
-        }
-    }
-
-    private int toDigit(int b) throws IOException {
-        if (b >= 0x30 && b <= 0x39) {
-            return b - 0x30;
-        }
-        if (b >= 0x41 && b <= 0x46) {
-            return b - 0x41 + 10;
-        }
-        if (b >= 0x61 && b <= 0x66) {
-            return b - 0x61 + 10;
-        }
-        throw new IOException("Invalid chunk header byte " + b);
-    }
-
-    private void request(long value) throws IOException {
-        try {
-            flowController.request(value);
-        } catch (InterruptedException e) {
-            throw new IOException(e);
-        }
-    }
-
-    private void pushBodyFixed(ByteBuffer b) throws IOException {
-        lastBufferUsed = b;
-        for (int remaining = contentLength; remaining > 0;) {
-            int bufsize = b.remaining();
-            if (bufsize > remaining) {
-                // more data available than required, must copy
-                lastBufferUsed = b;
-                b = copyBuffer(b, remaining);
-                remaining = 0;
-            } else {
-                // pass entire buffer up to user
-                remaining -= bufsize;
-                compactBuffer(b);
-            }
-            request(1); // wait till we can send
-            pusher.onResponseBodyChunk(b);
-            if (remaining > 0) {
-                b = connection.read();
-                if (b == null) {
-                    throw new IOException("Error reading response");
-                }
-                lastBufferUsed = b;
-            }
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ResponseHeaders.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,479 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * Reads response headers off channel, in blocking mode. Entire header
- * block is collected in a byte[]. The offset location of the start of
- * each header name is recorded in an array to facilitate later searching.
- *
- * The location of "Content-length" is recorded explicitly. Similar approach
- * could be taken for other common headers.
- *
- * This class is not thread-safe
- */
-class ResponseHeaders implements HttpHeaders {
-
-    static final int DATA_SIZE = 16 * 1024;  // initial space for headers
-    static final int NUM_HEADERS = 50; // initial expected max number of headers
-
-    final HttpConnection connection;
-    byte[] data;
-    int contentlen = -2; // means not initialized
-    ByteBuffer buffer;
-
-    /**
-     * Following used for scanning the array looking for:
-     *      - well known headers
-     *      - end of header block
-     */
-    int[] headerOffsets; // index into data
-    int numHeaders;
-    int count;
-
-    ByteBuffer residue; // after headers processed, data may be here
-
-    ResponseHeaders(HttpConnection connection, ByteBuffer buffer) {
-        this.connection = connection;
-        initOffsets();
-        this.buffer = buffer;
-        data = new byte[DATA_SIZE];
-    }
-
-    int getContentLength() throws IOException {
-        if (contentlen != -2) {
-            return contentlen;
-        }
-        int[] search = findHeaderValue("Content-length");
-        if (search[0] == -1) {
-            contentlen = -1;
-            return -1;
-        }
-
-        int i = search[0];
-
-        while (data[i] == ' ' || data[i] == '\t') {
-            i++;
-            if (i == data.length || data[i] == CR || data[i] == LF) {
-                throw new IOException("Bad header");
-            }
-        }
-        contentlen = 0;
-        int digit = data[i++] - 0x30;
-        while (digit >= 0 && digit <= 9) {
-            contentlen = contentlen * 10 + digit;
-            digit = data[i++] - 0x30;
-        }
-        return contentlen;
-    }
-
-    void log() {
-        populateMap(false);
-    }
-
-    void  populateMap(boolean clearOffsets) {
-        StringBuilder sb;
-
-        for (int i = 0; i < numHeaders; i++) {
-            sb = new StringBuilder(32);
-            int offset = headerOffsets[i];
-            if (offset == -1) {
-                continue;
-            }
-            int j;
-            for (j=0; data[offset+j] != ':'; j++) {
-                // byte to char promotion ok for US-ASCII
-                sb.append((char)data[offset+j]);
-            }
-            String name = sb.toString();
-            List<String> l = getOrCreate(name);
-            addEntry(l, name, offset + j + 1);
-            // clear the offset
-            if (clearOffsets)
-                headerOffsets[i] = -1;
-        }
-    }
-
-    void addEntry(List<String> l, String name, int j) {
-
-        while (data[j] == ' ' || data[j] == '\t') {
-            j++;
-        }
-
-        int vstart = j;
-            // TODO: back slash ??
-
-        while (data[j] != CR) {
-            j++;
-        }
-        try {
-            String value = new String(data, vstart, j - vstart, "US-ASCII");
-            l.add(value);
-        } catch (UnsupportedEncodingException e) {
-            // can't happen
-            throw new InternalError(e);
-        }
-    }
-
-    // returns an int[2]: [0] = offset of value in data[]
-    // [1] = offset in headerOffsets. Both are -1 in error
-
-    private int[] findHeaderValue(String name) {
-        int[] result = new int[2];
-        byte[] namebytes = getBytes(name);
-
- outer: for (int i = 0; i < numHeaders; i++) {
-            int offset = headerOffsets[i];
-            if (offset == -1) {
-                continue;
-            }
-
-            for (int j=0; j<namebytes.length; j++) {
-                if (namebytes[j] != lowerCase(data[offset+j])) {
-                    continue outer;
-                }
-            }
-            // next char must be ':'
-            if (data[offset+namebytes.length] != ':') {
-                continue;
-            }
-            result[0] = offset+namebytes.length + 1;
-            result[1] = i;
-            return result;
-        }
-        result[0] = -1;
-        result[1] = -1;
-        return result;
-    }
-
-    /**
-     * Populates the map for header values with the given name.
-     * The offsets are cleared for any that are found, so they don't
-     * get repeatedly searched.
-     */
-    List<String> populateMapEntry(String name) {
-        List<String> l = getOrCreate(name);
-        int[] search = findHeaderValue(name);
-        while (search[0] != -1) {
-            addEntry(l, name, search[0]);
-            // clear the offset
-            headerOffsets[search[1]] = -1;
-            search = findHeaderValue(name);
-        }
-        return l;
-    }
-
-    static final Locale usLocale = Locale.US;
-    static final Charset ascii = StandardCharsets.US_ASCII;
-
-    private byte[] getBytes(String name) {
-        return name.toLowerCase(usLocale).getBytes(ascii);
-    }
-
-    /*
-     * We read buffers in a loop until we detect end of headers
-     * CRLFCRLF. Each byte received is copied into the byte[] data
-     * The position of the first byte of each header (after a CRLF)
-     * is recorded in a separate array showing the location of
-     * each header name.
-     */
-    void initHeaders() throws IOException {
-
-        inHeaderName = true;
-        endOfHeader = true;
-
-        for (int numBuffers = 0; true; numBuffers++) {
-
-            if (numBuffers > 0) {
-                buffer = connection.read();
-            }
-
-            if (buffer == null) {
-                throw new IOException("Error reading headers");
-            }
-
-            if (!buffer.hasRemaining()) {
-                continue;
-            }
-
-            // Position set to first byte
-            int start = buffer.position();
-            byte[] backing = buffer.array();
-            int len = buffer.limit() - start;
-
-            for (int i = 0; i < len; i++) {
-                byte b = backing[i + start];
-                if (inHeaderName) {
-                    b = lowerCase(b);
-                }
-                if (b == ':') {
-                    inHeaderName = false;
-                }
-                data[count++] = b;
-                checkByte(b);
-                if (firstChar) {
-                    recordHeaderOffset(count-1);
-                    firstChar = false;
-                }
-                if (endOfHeader && numHeaders == 0) {
-                    // empty headers
-                    endOfAllHeaders = true;
-                }
-                if (endOfAllHeaders) {
-                    int newposition = i + 1 + start;
-                    if (newposition <= buffer.limit()) {
-                        buffer.position(newposition);
-                        residue = buffer;
-                    } else {
-                        residue = null;
-                    }
-                    return;
-                }
-
-                if (count == data.length) {
-                    resizeData();
-                }
-            }
-        }
-    }
-
-    static final int CR = 13;
-    static final int LF = 10;
-    int crlfCount = 0;
-
-    // results of checkByte()
-    boolean endOfHeader; // just seen LF after CR before
-    boolean endOfAllHeaders; // just seen LF after CRLFCR before
-    boolean firstChar; //
-    boolean inHeaderName; // examining header name
-
-    void checkByte(byte b) throws IOException {
-        if (endOfHeader &&  b != CR && b != LF)
-            firstChar = true;
-        endOfHeader = false;
-        endOfAllHeaders = false;
-        switch (crlfCount) {
-            case 0:
-                crlfCount = b == CR ? 1 : 0;
-                break;
-            case 1:
-                crlfCount = b == LF ? 2 : 0;
-                endOfHeader = true;
-                inHeaderName = true;
-                break;
-            case 2:
-                crlfCount = b == CR ? 3 : 0;
-                break;
-            case 3:
-                if (b != LF) {
-                    throw new IOException("Bad header block termination");
-                }
-                endOfAllHeaders = true;
-                break;
-        }
-    }
-
-    byte lowerCase(byte b) {
-        if (b >= 0x41 && b <= 0x5A)
-            b = (byte)(b + 32);
-        return b;
-    }
-
-    void resizeData() {
-        int oldlen = data.length;
-        int newlen = oldlen * 2;
-        byte[] newdata = new byte[newlen];
-        System.arraycopy(data, 0, newdata, 0, oldlen);
-        data = newdata;
-    }
-
-    final void initOffsets() {
-        headerOffsets = new int[NUM_HEADERS];
-        numHeaders = 0;
-    }
-
-    ByteBuffer getResidue() {
-        return residue;
-    }
-
-    void recordHeaderOffset(int index) {
-        if (numHeaders >= headerOffsets.length) {
-            int oldlen = headerOffsets.length;
-            int newlen = oldlen * 2;
-            int[] new1 = new int[newlen];
-            System.arraycopy(headerOffsets, 0, new1, 0, oldlen);
-            headerOffsets = new1;
-        }
-        headerOffsets[numHeaders++] = index;
-    }
-
-    /**
-     * As entries are read from the byte[] they are placed in here
-     * So we always check this map first
-     */
-    Map<String,List<String>> headers = new HashMap<>();
-
-    @Override
-    public Optional<String> firstValue(String name) {
-        List<String> l =  allValues(name);
-        if (l == null || l.isEmpty()) {
-            return Optional.ofNullable(null);
-        } else {
-            return Optional.of(l.get(0));
-        }
-    }
-
-    @Override
-    public List<String> allValues(String name) {
-        name = name.toLowerCase(usLocale);
-        List<String> l = headers.get(name);
-        if (l == null) {
-            l = populateMapEntry(name);
-        }
-        return Collections.unmodifiableList(l);
-    }
-
-    // Delegates map to HashMap but converts keys to lower case
-
-    static class HeaderMap implements Map<String,List<String>> {
-        Map<String,List<String>> inner;
-
-        HeaderMap(Map<String,List<String>> inner) {
-            this.inner = inner;
-        }
-        @Override
-        public int size() {
-            return inner.size();
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return inner.isEmpty();
-        }
-
-        @Override
-        public boolean containsKey(Object key) {
-            if (!(key instanceof String)) {
-                return false;
-            }
-            String s = ((String)key).toLowerCase(usLocale);
-            return inner.containsKey(s);
-        }
-
-        @Override
-        public boolean containsValue(Object value) {
-            return inner.containsValue(value);
-        }
-
-        @Override
-        public List<String> get(Object key) {
-            String s = ((String)key).toLowerCase(usLocale);
-            return inner.get(s);
-        }
-
-        @Override
-        public List<String> put(String key, List<String> value) {
-            throw new UnsupportedOperationException("Not supported");
-        }
-
-        @Override
-        public List<String> remove(Object key) {
-            throw new UnsupportedOperationException("Not supported");
-        }
-
-        @Override
-        public void putAll(Map<? extends String, ? extends List<String>> m) {
-            throw new UnsupportedOperationException("Not supported");
-        }
-
-        @Override
-        public void clear() {
-            throw new UnsupportedOperationException("Not supported");
-        }
-
-        @Override
-        public Set<String> keySet() {
-            return inner.keySet();
-        }
-
-        @Override
-        public Collection<List<String>> values() {
-            return inner.values();
-        }
-
-        @Override
-        public Set<Entry<String, List<String>>> entrySet() {
-            return inner.entrySet();
-        }
-    }
-
-    @Override
-    public Map<String, List<String>> map() {
-        populateMap(true);
-        return new HeaderMap(headers);
-    }
-
-    Map<String, List<String>> mapInternal() {
-        populateMap(false);
-        return new HeaderMap(headers);
-    }
-
-    private List<String> getOrCreate(String name) {
-        List<String> l = headers.get(name);
-        if (l == null) {
-            l = new LinkedList<>();
-            headers.put(name, l);
-        }
-        return l;
-    }
-
-    @Override
-    public Optional<Long> firstValueAsLong(String name) {
-        List<String> l =  allValues(name);
-        if (l == null) {
-            return Optional.ofNullable(null);
-        } else {
-            String v = l.get(0);
-            Long lv = Long.parseLong(v);
-            return Optional.of(lv);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SSLConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CompletableFuture;
-import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.SSLParameters;
-import java.net.http.SSLDelegate.BufType;
-import java.net.http.SSLDelegate.WrapperResult;
-
-/**
- * An SSL connection built on a Plain TCP connection.
- */
-class SSLConnection extends HttpConnection {
-
-    PlainHttpConnection delegate;
-    SSLDelegate sslDelegate;
-    final String[] alpn;
-
-    @Override
-    public CompletableFuture<Void> connectAsync() {
-        return delegate.connectAsync()
-                .thenCompose((Void v) -> {
-                    CompletableFuture<Void> cf = new CompletableFuture<>();
-                    try {
-                        this.sslDelegate = new SSLDelegate(delegate.channel(),
-                                                           client,
-                                                           alpn);
-                        cf.complete(null);
-                    } catch (IOException e) {
-                        cf.completeExceptionally(e);
-                    }
-                    return cf;
-                });
-    }
-
-    @Override
-    public void connect() throws IOException {
-        delegate.connect();
-        this.sslDelegate = new SSLDelegate(delegate.channel(), client, alpn);
-    }
-
-    SSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) {
-        super(addr, client);
-        this.alpn = ap;
-        delegate = new PlainHttpConnection(addr, client);
-    }
-
-    @Override
-    SSLParameters sslParameters() {
-        return sslDelegate.getSSLParameters();
-    }
-
-    @Override
-    public String toString() {
-        return "SSLConnection: " + super.toString();
-    }
-
-    private static long countBytes(ByteBuffer[] buffers, int start, int length) {
-        long c = 0;
-        for (int i=0; i<length; i++) {
-            c+= buffers[start+i].remaining();
-        }
-        return c;
-    }
-
-    @Override
-    ConnectionPool.CacheKey cacheKey() {
-        return ConnectionPool.cacheKey(address, null);
-    }
-
-    @Override
-    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
-        //debugPrint("Send", buffers, start, number);
-        long l = countBytes(buffers, start, number);
-        WrapperResult r = sslDelegate.sendData(buffers, start, number);
-        if (r.result.getStatus() == Status.CLOSED) {
-            if (l > 0) {
-                throw new IOException("SSLHttpConnection closed");
-            }
-        }
-        return l;
-    }
-
-    @Override
-    long write(ByteBuffer buffer) throws IOException {
-        //debugPrint("Send", buffer);
-        long l = buffer.remaining();
-        WrapperResult r = sslDelegate.sendData(buffer);
-        if (r.result.getStatus() == Status.CLOSED) {
-            if (l > 0) {
-                throw new IOException("SSLHttpConnection closed");
-            }
-        }
-        return l;
-    }
-
-    @Override
-    public void close() {
-        Utils.close(delegate.channel());
-    }
-
-    @Override
-    protected ByteBuffer readImpl(int length) throws IOException {
-        ByteBuffer buf = sslDelegate.allocate(BufType.PACKET, length);
-        WrapperResult r = sslDelegate.recvData(buf);
-        // TODO: check for closure
-        String s = "Receive) ";
-        //debugPrint(s, r.buf);
-        return r.buf;
-    }
-
-    @Override
-    protected int readImpl(ByteBuffer buf) throws IOException {
-        // TODO: need to ensure that buf is big enough for application data
-        WrapperResult r = sslDelegate.recvData(buf);
-        // TODO: check for closure
-        String s = "Receive) ";
-        //debugPrint(s, r.buf);
-        if (r.result.bytesProduced() > 0) {
-            assert buf == r.buf;
-        }
-        return r.result.bytesProduced();
-    }
-
-    @Override
-    boolean connected() {
-        return delegate.connected();
-    }
-
-    @Override
-    SocketChannel channel() {
-        return delegate.channel();
-    }
-
-    @Override
-    CompletableFuture<Void> whenReceivingResponse() {
-        return delegate.whenReceivingResponse();
-    }
-
-    @Override
-    boolean isSecure() {
-        return true;
-    }
-
-    @Override
-    boolean isProxied() {
-        return false;
-    }
-
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SSLDelegate.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,476 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.Arrays;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
-import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.*;
-import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
-
-/**
- * Implements the mechanics of SSL by managing an SSLEngine object.
- * One of these is associated with each SSLConnection.
- */
-class SSLDelegate {
-
-    final SSLEngine engine;
-    final EngineWrapper wrapper;
-    final Lock handshaking = new ReentrantLock();
-    final SSLParameters sslParameters;
-    final SocketChannel chan;
-    final HttpClientImpl client;
-
-    // alpn[] may be null
-    SSLDelegate(SocketChannel chan, HttpClientImpl client, String[] alpn)
-        throws IOException
-    {
-        SSLContext context = client.sslContext();
-        engine = context.createSSLEngine();
-        engine.setUseClientMode(true);
-        SSLParameters sslp = client.sslParameters().orElse(null);
-        if (sslp == null) {
-            sslp = context.getSupportedSSLParameters();
-        }
-        sslParameters = Utils.copySSLParameters(sslp);
-        if (alpn != null) {
-            sslParameters.setApplicationProtocols(alpn);
-            Log.logSSL("Setting application protocols: " + Arrays.toString(alpn));
-        } else {
-            Log.logSSL("No application protocols proposed");
-        }
-        engine.setSSLParameters(sslParameters);
-        wrapper = new EngineWrapper(chan, engine);
-        this.chan = chan;
-        this.client = client;
-    }
-
-    SSLParameters getSSLParameters() {
-        return sslParameters;
-    }
-
-    private static long countBytes(ByteBuffer[] buffers, int start, int number) {
-        long c = 0;
-        for (int i=0; i<number; i++) {
-            c+= buffers[start+i].remaining();
-        }
-        return c;
-    }
-
-
-    static class WrapperResult {
-        static WrapperResult createOK() {
-            WrapperResult r = new WrapperResult();
-            r.buf = null;
-            r.result = new SSLEngineResult(Status.OK, NOT_HANDSHAKING, 0, 0);
-            return r;
-        }
-        SSLEngineResult result;
-
-        /* if passed in buffer was not big enough then the a reallocated buffer
-         * is returned here  */
-        ByteBuffer buf;
-    }
-
-    int app_buf_size;
-    int packet_buf_size;
-
-    enum BufType {
-        PACKET,
-        APPLICATION
-    };
-
-    ByteBuffer allocate (BufType type) {
-        return allocate (type, -1);
-    }
-
-    // TODO: Use buffer pool for this
-    ByteBuffer allocate (BufType type, int len) {
-        assert engine != null;
-        synchronized (this) {
-            int size;
-            if (type == BufType.PACKET) {
-                if (packet_buf_size == 0) {
-                    SSLSession sess = engine.getSession();
-                    packet_buf_size = sess.getPacketBufferSize();
-                }
-                if (len > packet_buf_size) {
-                    packet_buf_size = len;
-                }
-                size = packet_buf_size;
-            } else {
-                if (app_buf_size == 0) {
-                    SSLSession sess = engine.getSession();
-                    app_buf_size = sess.getApplicationBufferSize();
-                }
-                if (len > app_buf_size) {
-                    app_buf_size = len;
-                }
-                size = app_buf_size;
-            }
-            return ByteBuffer.allocate (size);
-        }
-    }
-
-    /* reallocates the buffer by :-
-     * 1. creating a new buffer double the size of the old one
-     * 2. putting the contents of the old buffer into the new one
-     * 3. set xx_buf_size to the new size if it was smaller than new size
-     *
-     * flip is set to true if the old buffer needs to be flipped
-     * before it is copied.
-     */
-    private ByteBuffer realloc (ByteBuffer b, boolean flip, BufType type) {
-        synchronized (this) {
-            int nsize = 2 * b.capacity();
-            ByteBuffer n = allocate (type, nsize);
-            if (flip) {
-                b.flip();
-            }
-            n.put(b);
-            b = n;
-        }
-        return b;
-    }
-
-    /**
-     * This is a thin wrapper over SSLEngine and the SocketChannel, which
-     * guarantees the ordering of wraps/unwraps with respect to the underlying
-     * channel read/writes. It handles the UNDER/OVERFLOW status codes
-     * It does not handle the handshaking status codes, or the CLOSED status code
-     * though once the engine is closed, any attempt to read/write to it
-     * will get an exception.  The overall result is returned.
-     * It functions synchronously/blocking
-     */
-    class EngineWrapper {
-
-        SocketChannel chan;
-        SSLEngine engine;
-        Object wrapLock, unwrapLock;
-        ByteBuffer unwrap_src, wrap_dst;
-        boolean closed = false;
-        int u_remaining; // the number of bytes left in unwrap_src after an unwrap()
-
-        EngineWrapper (SocketChannel chan, SSLEngine engine) throws IOException {
-            this.chan = chan;
-            this.engine = engine;
-            wrapLock = new Object();
-            unwrapLock = new Object();
-            unwrap_src = allocate(BufType.PACKET);
-            wrap_dst = allocate(BufType.PACKET);
-        }
-
-        void close () throws IOException {
-        }
-
-        WrapperResult wrapAndSend(ByteBuffer src, boolean ignoreClose)
-            throws IOException
-        {
-            ByteBuffer[] buffers = new ByteBuffer[1];
-            buffers[0] = src;
-            return wrapAndSend(buffers, 0, 1, ignoreClose);
-        }
-
-        /* try to wrap and send the data in src. Handles OVERFLOW.
-         * Might block if there is an outbound blockage or if another
-         * thread is calling wrap(). Also, might not send any data
-         * if an unwrap is needed.
-         */
-        WrapperResult wrapAndSend(ByteBuffer[] src,
-                                  int offset,
-                                  int len,
-                                  boolean ignoreClose)
-            throws IOException
-        {
-            if (closed && !ignoreClose) {
-                throw new IOException ("Engine is closed");
-            }
-            Status status;
-            WrapperResult r = new WrapperResult();
-            synchronized (wrapLock) {
-                wrap_dst.clear();
-                do {
-                    r.result = engine.wrap (src, offset, len, wrap_dst);
-                    status = r.result.getStatus();
-                    if (status == Status.BUFFER_OVERFLOW) {
-                        wrap_dst = realloc (wrap_dst, true, BufType.PACKET);
-                    }
-                } while (status == Status.BUFFER_OVERFLOW);
-                if (status == Status.CLOSED && !ignoreClose) {
-                    closed = true;
-                    return r;
-                }
-                if (r.result.bytesProduced() > 0) {
-                    wrap_dst.flip();
-                    int l = wrap_dst.remaining();
-                    assert l == r.result.bytesProduced();
-                    while (l>0) {
-                        l -= chan.write (wrap_dst);
-                    }
-                }
-            }
-            return r;
-        }
-
-        /* block until a complete message is available and return it
-         * in dst, together with the Result. dst may have been re-allocated
-         * so caller should check the returned value in Result
-         * If handshaking is in progress then, possibly no data is returned
-         */
-        WrapperResult recvAndUnwrap(ByteBuffer dst) throws IOException {
-            Status status;
-            WrapperResult r = new WrapperResult();
-            r.buf = dst;
-            if (closed) {
-                throw new IOException ("Engine is closed");
-            }
-            boolean needData;
-            if (u_remaining > 0) {
-                unwrap_src.compact();
-                unwrap_src.flip();
-                needData = false;
-            } else {
-                unwrap_src.clear();
-                needData = true;
-            }
-            synchronized (unwrapLock) {
-                int x;
-                do {
-                    if (needData) {
-                        do {
-                            x = chan.read (unwrap_src);
-                        } while (x == 0);
-                        if (x == -1) {
-                            throw new IOException ("connection closed for reading");
-                        }
-                        unwrap_src.flip();
-                    }
-                    r.result = engine.unwrap (unwrap_src, r.buf);
-                    status = r.result.getStatus();
-                    if (status == Status.BUFFER_UNDERFLOW) {
-                        if (unwrap_src.limit() == unwrap_src.capacity()) {
-                            /* buffer not big enough */
-                            unwrap_src = realloc (
-                                unwrap_src, false, BufType.PACKET
-                            );
-                        } else {
-                            /* Buffer not full, just need to read more
-                             * data off the channel. Reset pointers
-                             * for reading off SocketChannel
-                             */
-                            unwrap_src.position (unwrap_src.limit());
-                            unwrap_src.limit (unwrap_src.capacity());
-                        }
-                        needData = true;
-                    } else if (status == Status.BUFFER_OVERFLOW) {
-                        r.buf = realloc (r.buf, true, BufType.APPLICATION);
-                        needData = false;
-                    } else if (status == Status.CLOSED) {
-                        closed = true;
-                        r.buf.flip();
-                        return r;
-                    }
-                } while (status != Status.OK);
-            }
-            u_remaining = unwrap_src.remaining();
-            return r;
-        }
-    }
-
-    WrapperResult sendData (ByteBuffer src) throws IOException {
-        ByteBuffer[] buffers = new ByteBuffer[1];
-        buffers[0] = src;
-        return sendData(buffers, 0, 1);
-    }
-
-    /**
-     * send the data in the given ByteBuffer. If a handshake is needed
-     * then this is handled within this method. When this call returns,
-     * all of the given user data has been sent and any handshake has been
-     * completed. Caller should check if engine has been closed.
-     */
-    WrapperResult sendData (ByteBuffer[] src, int offset, int len) throws IOException {
-        WrapperResult r = WrapperResult.createOK();
-        while (countBytes(src, offset, len) > 0) {
-            r = wrapper.wrapAndSend(src, offset, len, false);
-            Status status = r.result.getStatus();
-            if (status == Status.CLOSED) {
-                doClosure ();
-                return r;
-            }
-            HandshakeStatus hs_status = r.result.getHandshakeStatus();
-            if (hs_status != HandshakeStatus.FINISHED &&
-                hs_status != HandshakeStatus.NOT_HANDSHAKING)
-            {
-                doHandshake(hs_status);
-            }
-        }
-        return r;
-    }
-
-    /**
-     * read data thru the engine into the given ByteBuffer. If the
-     * given buffer was not large enough, a new one is allocated
-     * and returned. This call handles handshaking automatically.
-     * Caller should check if engine has been closed.
-     */
-    WrapperResult recvData (ByteBuffer dst) throws IOException {
-        /* we wait until some user data arrives */
-        int mark = dst.position();
-        WrapperResult r = null;
-        int pos = dst.position();
-        while (dst.position() == pos) {
-            r = wrapper.recvAndUnwrap (dst);
-            dst = (r.buf != dst) ? r.buf: dst;
-            Status status = r.result.getStatus();
-            if (status == Status.CLOSED) {
-                doClosure ();
-                return r;
-            }
-
-            HandshakeStatus hs_status = r.result.getHandshakeStatus();
-            if (hs_status != HandshakeStatus.FINISHED &&
-                hs_status != HandshakeStatus.NOT_HANDSHAKING)
-            {
-                doHandshake (hs_status);
-            }
-        }
-        Utils.flipToMark(dst, mark);
-        return r;
-    }
-
-    /* we've received a close notify. Need to call wrap to send
-     * the response
-     */
-    void doClosure () throws IOException {
-        try {
-            handshaking.lock();
-            ByteBuffer tmp = allocate(BufType.APPLICATION);
-            WrapperResult r;
-            do {
-                tmp.clear();
-                tmp.flip ();
-                r = wrapper.wrapAndSend(tmp, true);
-            } while (r.result.getStatus() != Status.CLOSED);
-        } finally {
-            handshaking.unlock();
-        }
-    }
-
-    /* do the (complete) handshake after acquiring the handshake lock.
-     * If two threads call this at the same time, then we depend
-     * on the wrapper methods being idempotent. eg. if wrapAndSend()
-     * is called with no data to send then there must be no problem
-     */
-    @SuppressWarnings("fallthrough")
-    void doHandshake (HandshakeStatus hs_status) throws IOException {
-        boolean wasBlocking = false;
-        try {
-            wasBlocking = chan.isBlocking();
-            handshaking.lock();
-            chan.configureBlocking(true);
-            ByteBuffer tmp = allocate(BufType.APPLICATION);
-            while (hs_status != HandshakeStatus.FINISHED &&
-                   hs_status != HandshakeStatus.NOT_HANDSHAKING)
-            {
-                WrapperResult r = null;
-                switch (hs_status) {
-                    case NEED_TASK:
-                        Runnable task;
-                        while ((task = engine.getDelegatedTask()) != null) {
-                            /* run in current thread, because we are already
-                             * running an external Executor
-                             */
-                            task.run();
-                        }
-                        /* fall thru - call wrap again */
-                    case NEED_WRAP:
-                        tmp.clear();
-                        tmp.flip();
-                        r = wrapper.wrapAndSend(tmp, false);
-                        break;
-
-                    case NEED_UNWRAP:
-                        tmp.clear();
-                        r = wrapper.recvAndUnwrap (tmp);
-                        if (r.buf != tmp) {
-                            tmp = r.buf;
-                        }
-                        assert tmp.position() == 0;
-                        break;
-                }
-                hs_status = r.result.getHandshakeStatus();
-            }
-            Log.logSSL(getSessionInfo());
-            if (!wasBlocking) {
-                chan.configureBlocking(false);
-            }
-        } finally {
-            handshaking.unlock();
-        }
-    }
-
-    static void printParams(SSLParameters p) {
-        System.out.println("SSLParameters:");
-        if (p == null) {
-            System.out.println("Null params");
-            return;
-        }
-        for (String cipher : p.getCipherSuites()) {
-                System.out.printf("cipher: %s\n", cipher);
-        }
-        for (String approto : p.getApplicationProtocols()) {
-                System.out.printf("application protocol: %s\n", approto);
-        }
-        for (String protocol : p.getProtocols()) {
-                System.out.printf("protocol: %s\n", protocol);
-        }
-        if (p.getServerNames() != null)
-        for (SNIServerName sname : p.getServerNames()) {
-                System.out.printf("server name: %s\n", sname.toString());
-        }
-    }
-
-    String getSessionInfo() {
-        StringBuilder sb = new StringBuilder();
-        String application = engine.getApplicationProtocol();
-        SSLSession sess = engine.getSession();
-        String cipher = sess.getCipherSuite();
-        String protocol = sess.getProtocol();
-        sb.append("Handshake complete alpn: ")
-                .append(application)
-                .append(", Cipher: ")
-                .append(cipher)
-                .append(", Protocol: ")
-                .append(protocol);
-        return sb.toString();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SSLTunnelConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.security.AccessControlContext;
-import java.util.concurrent.CompletableFuture;
-import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.SSLParameters;
-import java.net.http.SSLDelegate.BufType;
-import java.net.http.SSLDelegate.WrapperResult;
-
-/**
- * An SSL tunnel built on a Plain (CONNECT) TCP tunnel.
- */
-class SSLTunnelConnection extends HttpConnection {
-
-    final PlainTunnelingConnection delegate;
-    protected SSLDelegate sslDelegate;
-    private volatile boolean connected;
-
-    @Override
-    public void connect() throws IOException, InterruptedException {
-        delegate.connect();
-        this.sslDelegate = new SSLDelegate(delegate.channel(), client, null);
-        connected = true;
-    }
-
-    @Override
-    boolean connected() {
-        return connected && delegate.connected();
-    }
-
-    @Override
-    public CompletableFuture<Void> connectAsync() {
-        return delegate.connectAsync()
-            .thenAccept((Void v) -> {
-                try {
-                    // can this block?
-                    this.sslDelegate = new SSLDelegate(delegate.channel(),
-                                                       client,
-                                                       null);
-                    connected = true;
-                } catch (IOException e) {
-                    throw new UncheckedIOException(e);
-                }
-            });
-    }
-
-    SSLTunnelConnection(InetSocketAddress addr,
-                        HttpClientImpl client,
-                        InetSocketAddress proxy,
-                        AccessControlContext acc) {
-        super(addr, client);
-        delegate = new PlainTunnelingConnection(addr, proxy, client, acc);
-    }
-
-    @Override
-    SSLParameters sslParameters() {
-        return sslDelegate.getSSLParameters();
-    }
-
-    @Override
-    public String toString() {
-        return "SSLTunnelConnection: " + super.toString();
-    }
-
-    private static long countBytes(ByteBuffer[] buffers, int start, int number) {
-        long c = 0;
-        for (int i=0; i<number; i++) {
-            c+= buffers[start+i].remaining();
-        }
-        return c;
-    }
-
-    @Override
-    ConnectionPool.CacheKey cacheKey() {
-        return ConnectionPool.cacheKey(address, delegate.proxyAddr);
-    }
-
-    @Override
-    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
-        //debugPrint("Send", buffers, start, number);
-        long l = countBytes(buffers, start, number);
-        WrapperResult r = sslDelegate.sendData(buffers, start, number);
-        if (r.result.getStatus() == Status.CLOSED) {
-            if (l > 0) {
-                throw new IOException("SSLHttpConnection closed");
-            }
-        }
-        return l;
-    }
-
-    @Override
-    long write(ByteBuffer buffer) throws IOException {
-        //debugPrint("Send", buffer);
-        long l = buffer.remaining();
-        WrapperResult r = sslDelegate.sendData(buffer);
-        if (r.result.getStatus() == Status.CLOSED) {
-            if (l > 0) {
-                throw new IOException("SSLHttpConnection closed");
-            }
-        }
-        return l;
-    }
-
-    @Override
-    public void close() {
-        Utils.close(delegate.channel());
-    }
-
-    @Override
-    protected ByteBuffer readImpl(int length) throws IOException {
-        ByteBuffer buf = sslDelegate.allocate(BufType.PACKET, length);
-        WrapperResult r = sslDelegate.recvData(buf);
-        // TODO: check for closure
-        String s = "Receive) ";
-        //debugPrint(s, r.buf);
-        return r.buf;
-    }
-
-    @Override
-    protected int readImpl(ByteBuffer buf) throws IOException {
-        WrapperResult r = sslDelegate.recvData(buf);
-        // TODO: check for closure
-        String s = "Receive) ";
-        //debugPrint(s, r.buf);
-        if (r.result.bytesProduced() > 0) {
-            assert buf == r.buf;
-        }
-
-        return r.result.bytesProduced();
-    }
-
-    @Override
-    SocketChannel channel() {
-        return delegate.channel();
-    }
-
-    @Override
-    CompletableFuture<Void> whenReceivingResponse() {
-        return delegate.whenReceivingResponse();
-    }
-
-    @Override
-    boolean isSecure() {
-        return true;
-    }
-
-    @Override
-    boolean isProxied() {
-        return true;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SettingsFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class SettingsFrame extends Http2Frame {
-
-    int[] parameters;
-
-    public static final int TYPE = 0x4;
-
-    // Flags
-    public static final int ACK = 0x1;
-
-    @Override
-    String flagAsString(int flag) {
-        switch (flag) {
-        case ACK:
-            return "ACK";
-        }
-        return super.flagAsString(flag);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(super.toString())
-          .append(" Settings: ");
-
-        for (int i = 0; i < MAX_PARAM; i++) {
-            if (parameters[i] != -1) {
-                sb.append(name(i))
-                  .append("=")
-                  .append(Integer.toString(parameters[i]))
-                  .append(' ');
-            }
-        }
-        return sb.toString();
-    }
-
-    // Parameters
-    public static final int HEADER_TABLE_SIZE = 0x1;
-    public static final int ENABLE_PUSH = 0x2;
-    public static final int MAX_CONCURRENT_STREAMS = 0x3;
-    public static final int INITIAL_WINDOW_SIZE = 0x4;
-    public static final int MAX_FRAME_SIZE = 0x5;
-    public static final int MAX_HEADER_LIST_SIZE = 0x6;
-
-    private String name(int i) {
-        switch (i+1) {
-        case HEADER_TABLE_SIZE:
-            return "HEADER_TABLE_SIZE";
-        case ENABLE_PUSH:
-            return "ENABLE_PUSH";
-        case MAX_CONCURRENT_STREAMS:
-            return "MAX_CONCURRENT_STREAMS";
-        case INITIAL_WINDOW_SIZE:
-            return "INITIAL_WINDOW_SIZE";
-        case MAX_FRAME_SIZE:
-            return "MAX_FRAME_SIZE";
-        case MAX_HEADER_LIST_SIZE:
-            return "MAX_HEADER_LIST_SIZE";
-        }
-        return "unknown parameter";
-    }
-    public static final int MAX_PARAM = 0x6;
-
-    public SettingsFrame() {
-        type = TYPE;
-        parameters = new int [MAX_PARAM];
-        for (int i=0; i < parameters.length; i++) {
-            parameters[i] = -1;
-        }
-    }
-
-    public int getParameter(int paramID) {
-        if (paramID > MAX_PARAM) {
-            throw new IllegalArgumentException("illegal parameter");
-        }
-        return parameters[paramID-1];
-    }
-
-    public SettingsFrame setParameter(int paramID, int value) {
-        if (paramID > MAX_PARAM) {
-            throw new IllegalArgumentException("illegal parameter");
-        }
-        parameters[paramID-1] = value;
-        return this;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if (length % 6 != 0) {
-            throw new IOException("Protocol error: invalid settings frame");
-        }
-        int n = length / 6;
-        for (int i=0; i<n; i++) {
-            int id = bc.getShort();
-            int val = bc.getInt();
-            if (id > 0 || id <= MAX_PARAM) {
-                // a known parameter. Ignore otherwise
-                parameters[id-1] = val;
-            }
-        }
-    }
-
-    @Override
-    void computeLength() {
-        length = 0;
-        for (int i : parameters) {
-            if (i != -1) {
-                length += 6;
-            }
-        }
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(length);
-        for (int i = 0; i < MAX_PARAM; i++) {
-            if (parameters[i] != -1) {
-                buf.putShort((short)(i+1));
-                buf.putInt(parameters[i]);
-            }
-        }
-    }
-
-    private static final int K = 1024;
-
-    public static SettingsFrame getDefaultSettings() {
-        SettingsFrame f = new SettingsFrame();
-        // TODO: check these values
-        f.setParameter(ENABLE_PUSH, 1);
-        f.setParameter(HEADER_TABLE_SIZE, 4 * K);
-        f.setParameter(MAX_CONCURRENT_STREAMS, 35);
-        f.setParameter(INITIAL_WINDOW_SIZE, 16 * K);
-        f.setParameter(MAX_FRAME_SIZE, 16 * K);
-        return f;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,856 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 sun.net.httpclient.hpack.DecodingCallback;
-
-import java.io.IOException;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.BiFunction;
-import java.util.function.LongConsumer;
-
-/**
- * Http/2 Stream handling.
- *
- * REQUESTS
- *
- * sendHeadersOnly() -- assembles HEADERS frame and puts on connection outbound Q
- *
- * sendRequest() -- sendHeadersOnly() + sendBody()
- *
- * sendBody() -- in calling thread: obeys all flow control (so may block)
- *               obtains data from request body processor and places on connection
- *               outbound Q.
- *
- * sendBodyAsync() -- calls sendBody() in an executor thread.
- *
- * sendHeadersAsync() -- calls sendHeadersOnly() which does not block
- *
- * sendRequestAsync() -- calls sendRequest() in an executor thread
- *
- * RESPONSES
- *
- * Multiple responses can be received per request. Responses are queued up on
- * a LinkedList of CF<HttpResponse> and the the first one on the list is completed
- * with the next response
- *
- * getResponseAsync() -- queries list of response CFs and returns first one
- *               if one exists. Otherwise, creates one and adds it to list
- *               and returns it. Completion is achieved through the
- *               incoming() upcall from connection reader thread.
- *
- * getResponse() -- calls getResponseAsync() and waits for CF to complete
- *
- * responseBody() -- in calling thread: blocks for incoming DATA frames on
- *               stream inputQ. Obeys remote and local flow control so may block.
- *               Calls user response body processor with data buffers.
- *
- * responseBodyAsync() -- calls responseBody() in an executor thread.
- *
- * incoming() -- entry point called from connection reader thread. Frames are
- *               either handled immediately without blocking or for data frames
- *               placed on the stream's inputQ which is consumed by the stream's
- *               reader thread.
- *
- * PushedStream sub class
- * ======================
- * Sending side methods are not used because the request comes from a PUSH_PROMISE
- * frame sent by the server. When a PUSH_PROMISE is received the PushedStream
- * is created. PushedStream does not use responseCF list as there can be only
- * one response. The CF is created when the object created and when the response
- * HEADERS frame is received the object is completed.
- */
-class Stream extends ExchangeImpl {
-
-    final Queue<Http2Frame> inputQ;
-
-    volatile int streamid;
-
-    long responseContentLen = -1;
-    long responseBytesProcessed = 0;
-    long requestContentLen;
-
-    Http2Connection connection;
-    HttpClientImpl client;
-    final HttpRequestImpl request;
-    final DecodingCallback rspHeadersConsumer;
-    HttpHeadersImpl responseHeaders;
-    final HttpHeadersImpl requestHeaders;
-    final HttpHeadersImpl requestPseudoHeaders;
-    HttpResponse.BodyProcessor<?> responseProcessor;
-    final HttpRequest.BodyProcessor requestProcessor;
-    HttpResponse response;
-
-    // state flags
-    boolean requestSent, responseReceived;
-
-    final FlowController userRequestFlowController =
-            new FlowController();
-    final FlowController remoteRequestFlowController =
-            new FlowController();
-    final FlowController responseFlowController =
-            new FlowController();
-
-    final ExecutorWrapper executor;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
-        this.responseProcessor = processor;
-        CompletableFuture<T> cf;
-        try {
-            T body = processor.onResponseBodyStart(
-                    responseContentLen, responseHeaders,
-                    responseFlowController); // TODO: filter headers
-            if (body != null) {
-                cf = CompletableFuture.completedFuture(body);
-                receiveDataAsync(processor);
-            } else
-                cf = receiveDataAsync(processor);
-        } catch (IOException e) {
-            cf = CompletableFuture.failedFuture(e);
-        }
-        PushGroup<?> pg = request.pushGroup();
-        if (pg != null) {
-            // if an error occurs make sure it is recorded in the PushGroup
-            cf = cf.whenComplete((t,e) -> pg.pushError(e));
-        }
-        return cf;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("streamid: ")
-                .append(streamid);
-        return sb.toString();
-    }
-
-    // pushes entire response body into response processor
-    // blocking when required by local or remote flow control
-    void receiveData() throws IOException {
-        Http2Frame frame;
-        DataFrame df = null;
-        try {
-            do {
-                frame = inputQ.take();
-                if (!(frame instanceof DataFrame)) {
-                    assert false;
-                    continue;
-                }
-                df = (DataFrame) frame;
-                int len = df.getDataLength();
-                ByteBuffer[] buffers = df.getData();
-                for (ByteBuffer b : buffers) {
-                    responseFlowController.take();
-                    responseProcessor.onResponseBodyChunk(b);
-                }
-                sendWindowUpdate(len);
-            } while (!df.getFlag(DataFrame.END_STREAM));
-        } catch (InterruptedException e) {
-            throw new IOException(e);
-        }
-    }
-
-    private <T> CompletableFuture<T> receiveDataAsync(HttpResponse.BodyProcessor<T> processor) {
-        CompletableFuture<T> cf = new CompletableFuture<>();
-        executor.execute(() -> {
-            try {
-                receiveData();
-                T body = processor.onResponseComplete();
-                cf.complete(body);
-                responseReceived();
-            } catch (Throwable t) {
-                cf.completeExceptionally(t);
-            }
-        }, null);
-        return cf;
-    }
-
-    private void sendWindowUpdate(int increment)
-            throws IOException, InterruptedException {
-        if (increment == 0)
-            return;
-        LinkedList<Http2Frame> list = new LinkedList<>();
-        WindowUpdateFrame frame = new WindowUpdateFrame();
-        frame.streamid(streamid);
-        frame.setUpdate(increment);
-        list.add(frame);
-        frame = new WindowUpdateFrame();
-        frame.streamid(0);
-        frame.setUpdate(increment);
-        list.add(frame);
-        connection.sendFrames(list);
-    }
-
-    @Override
-    CompletableFuture<Void> sendBodyAsync() {
-        final CompletableFuture<Void> cf = new CompletableFuture<>();
-        executor.execute(() -> {
-            try {
-                sendBodyImpl();
-                cf.complete(null);
-            } catch (IOException | InterruptedException e) {
-                cf.completeExceptionally(e);
-            }
-        }, null);
-        return cf;
-    }
-
-    @SuppressWarnings("unchecked")
-    Stream(HttpClientImpl client, Http2Connection connection, Exchange e) {
-        super(e);
-        this.client = client;
-        this.connection = connection;
-        this.request = e.request();
-        this.requestProcessor = request.requestProcessor();
-        responseHeaders = new HttpHeadersImpl();
-        requestHeaders = new HttpHeadersImpl();
-        rspHeadersConsumer = (name, value) -> {
-            responseHeaders.addHeader(name.toString(), value.toString());
-        };
-        this.executor = client.executorWrapper();
-        //this.response_cf = new CompletableFuture<HttpResponseImpl>();
-        this.requestPseudoHeaders = new HttpHeadersImpl();
-        // NEW
-        this.inputQ = new Queue<>();
-    }
-
-    @SuppressWarnings("unchecked")
-    Stream(HttpClientImpl client, Http2Connection connection, HttpRequestImpl req) {
-        super(null);
-        this.client = client;
-        this.connection = connection;
-        this.request = req;
-        this.requestProcessor = null;
-        responseHeaders = new HttpHeadersImpl();
-        requestHeaders = new HttpHeadersImpl();
-        rspHeadersConsumer = (name, value) -> {
-            responseHeaders.addHeader(name.toString(), value.toString());
-        };
-        this.executor = client.executorWrapper();
-        //this.response_cf = new CompletableFuture<HttpResponseImpl>();
-        this.requestPseudoHeaders = new HttpHeadersImpl();
-        // NEW
-        this.inputQ = new Queue<>();
-    }
-
-    /**
-     * Entry point from Http2Connection reader thread.
-     *
-     * Data frames will be removed by response body thread.
-     *
-     * @param frame
-     * @throws IOException
-     */
-    void incoming(Http2Frame frame) throws IOException, InterruptedException {
-        if ((frame instanceof HeaderFrame) && ((HeaderFrame)frame).endHeaders()) {
-            // Complete headers accumulated. handle response.
-            // It's okay if there are multiple HeaderFrames.
-            handleResponse();
-        } else if (frame instanceof DataFrame) {
-            inputQ.put(frame);
-        } else {
-            otherFrame(frame);
-        }
-    }
-
-    void otherFrame(Http2Frame frame) throws IOException {
-        switch (frame.type()) {
-            case WindowUpdateFrame.TYPE:
-                incoming_windowUpdate((WindowUpdateFrame) frame);
-                break;
-            case ResetFrame.TYPE:
-                incoming_reset((ResetFrame) frame);
-                break;
-            case PriorityFrame.TYPE:
-                incoming_priority((PriorityFrame) frame);
-                break;
-            default:
-                String msg = "Unexpected frame: " + frame.toString();
-                throw new IOException(msg);
-        }
-    }
-
-    // The Hpack decoder decodes into one of these consumers of name,value pairs
-
-    DecodingCallback rspHeadersConsumer() {
-        return rspHeadersConsumer;
-    }
-
-    // create and return the HttpResponseImpl
-    protected void handleResponse() throws IOException {
-        HttpConnection c = connection.connection; // TODO: improve
-        long statusCode = responseHeaders
-                .firstValueAsLong(":status")
-                .orElseThrow(() -> new IOException("no statuscode in response"));
-
-        this.response = new HttpResponseImpl((int)statusCode, exchange, responseHeaders, null,
-                c.sslParameters(), HttpClient.Version.HTTP_2, c);
-        this.responseContentLen = responseHeaders
-                .firstValueAsLong("content-length")
-                .orElse(-1L);
-        // different implementations for normal streams and pushed streams
-        completeResponse(response);
-    }
-
-    void incoming_reset(ResetFrame frame) {
-        // TODO: implement reset
-        int error = frame.getErrorCode();
-        IOException e = new IOException(ErrorFrame.stringForCode(error));
-        completeResponseExceptionally(e);
-        throw new UnsupportedOperationException("Not implemented");
-    }
-
-    void incoming_priority(PriorityFrame frame) {
-        // TODO: implement priority
-        throw new UnsupportedOperationException("Not implemented");
-    }
-
-    void incoming_windowUpdate(WindowUpdateFrame frame) {
-        int amount = frame.getUpdate();
-        if (amount > 0)
-            remoteRequestFlowController.accept(amount);
-    }
-
-    void incoming_pushPromise(HttpRequestImpl pushReq, PushedStream pushStream) throws IOException {
-        if (Log.requests()) {
-            Log.logRequest("PUSH_PROMISE: " + pushReq.toString());
-        }
-        PushGroup<?> pushGroup = request.pushGroup();
-        if (pushGroup == null) {
-            cancelImpl(new IllegalStateException("unexpected push promise"));
-        }
-        // get the handler and call it.
-        BiFunction<HttpRequest,CompletableFuture<HttpResponse>,Boolean> ph =
-            pushGroup.pushHandler();
-
-        CompletableFuture<HttpResponse> pushCF = pushStream
-                .getResponseAsync(null)
-                .thenApply(r -> (HttpResponse)r);
-        boolean accept = ph.apply(pushReq, pushCF);
-        if (!accept) {
-            IOException ex = new IOException("Stream cancelled by user");
-            cancelImpl(ex);
-            pushCF.completeExceptionally(ex);
-        } else {
-            pushStream.requestSent();
-            pushGroup.addPush();
-        }
-    }
-
-    private OutgoingHeaders headerFrame(long contentLength) {
-        HttpHeadersImpl h = request.getSystemHeaders();
-        if (contentLength > 0) {
-            h.setHeader("content-length", Long.toString(contentLength));
-        }
-        setPseudoHeaderFields();
-        OutgoingHeaders f = new OutgoingHeaders(h, request.getUserHeaders(), this);
-        if (contentLength == 0) {
-            f.setFlag(HeadersFrame.END_STREAM);
-        }
-        return f;
-    }
-
-    private void setPseudoHeaderFields() {
-        HttpHeadersImpl hdrs = requestPseudoHeaders;
-        String method = request.method();
-        hdrs.setHeader(":method", method);
-        URI uri = request.uri();
-        hdrs.setHeader(":scheme", uri.getScheme());
-        // TODO: userinfo deprecated. Needs to be removed
-        hdrs.setHeader(":authority", uri.getAuthority());
-        // TODO: ensure header names beginning with : not in user headers
-        String query = uri.getQuery();
-        String path = uri.getPath();
-        if (path == null) {
-            if (method.equalsIgnoreCase("OPTIONS")) {
-                path = "*";
-            } else {
-                path = "/";
-            }
-        }
-        if (query != null) {
-            path += "?" + query;
-        }
-        hdrs.setHeader(":path", path);
-    }
-
-    HttpHeadersImpl getRequestPseudoHeaders() {
-        return requestPseudoHeaders;
-    }
-
-    @Override
-    HttpResponseImpl getResponse() throws IOException {
-        try {
-            if (request.timeval() > 0) {
-                return getResponseAsync(null).get(
-                        request.timeval(), TimeUnit.MILLISECONDS);
-            } else {
-                return getResponseAsync(null).join();
-            }
-        } catch (TimeoutException e) {
-            throw new HttpTimeoutException("Response timed out");
-        } catch (InterruptedException | ExecutionException | CompletionException e) {
-            Throwable t = e.getCause();
-            if (t instanceof IOException) {
-                throw (IOException)t;
-            }
-            throw new IOException(e);
-        }
-    }
-
-    @Override
-    void sendRequest() throws IOException, InterruptedException {
-        sendHeadersOnly();
-        sendBody();
-    }
-
-    /**
-     * A simple general purpose blocking flow controller
-     */
-    class FlowController implements LongConsumer {
-        int permits;
-
-        FlowController() {
-            this.permits = 0;
-        }
-
-        @Override
-        public synchronized void accept(long n) {
-            if (n < 1) {
-                throw new InternalError("FlowController.accept called with " + n);
-            }
-            if (permits == 0) {
-                permits += n;
-                notifyAll();
-            } else {
-                permits += n;
-            }
-        }
-
-        public synchronized void take() throws InterruptedException {
-            take(1);
-        }
-
-        public synchronized void take(int amount) throws InterruptedException {
-            assert permits >= 0;
-            while (amount > 0) {
-                int n = Math.min(amount, permits);
-                permits -= n;
-                amount -= n;
-                if (amount > 0)
-                    wait();
-            }
-        }
-    }
-
-    @Override
-    void sendHeadersOnly() throws IOException, InterruptedException {
-        if (Log.requests() && request != null) {
-            Log.logRequest(request.toString());
-        }
-        requestContentLen = requestProcessor.onRequestStart(request, userRequestFlowController);
-        OutgoingHeaders f = headerFrame(requestContentLen);
-        connection.sendFrame(f);
-    }
-
-    @Override
-    void sendBody() throws IOException, InterruptedException {
-        sendBodyImpl();
-    }
-
-    void registerStream(int id) {
-        this.streamid = id;
-        connection.putStream(this, streamid);
-    }
-
-    DataFrame getDataFrame() throws IOException, InterruptedException {
-        userRequestFlowController.take();
-        int maxpayloadLen = connection.getMaxSendFrameSize();
-        ByteBuffer buffer = connection.getBuffer();
-        buffer.limit(maxpayloadLen);
-        boolean complete = requestProcessor.onRequestBodyChunk(buffer);
-        buffer.flip();
-        int amount = buffer.remaining();
-        // wait for flow control if necessary. Following method will block
-        // until after headers frame is sent, so correct streamid is set.
-        remoteRequestFlowController.take(amount);
-        connection.obtainSendWindow(amount);
-
-        DataFrame df = new DataFrame();
-        df.streamid(streamid);
-        if (complete) {
-            df.setFlag(DataFrame.END_STREAM);
-        }
-        df.setData(buffer);
-        df.computeLength();
-        return df;
-    }
-
-
-    @Override
-    CompletableFuture<Void> sendHeadersAsync() {
-        try {
-            sendHeadersOnly();
-            return CompletableFuture.completedFuture(null);
-        } catch (IOException | InterruptedException ex) {
-            return CompletableFuture.failedFuture(ex);
-        }
-    }
-
-    /**
-     * A List of responses relating to this stream. Normally there is only
-     * one response, but intermediate responses like 100 are allowed
-     * and must be passed up to higher level before continuing. Deals with races
-     * such as if responses are returned before the CFs get created by
-     * getResponseAsync()
-     */
-
-    final List<CompletableFuture<HttpResponseImpl>> response_cfs = new ArrayList<>(5);
-
-    @Override
-    CompletableFuture<HttpResponseImpl> getResponseAsync(Void v) {
-        CompletableFuture<HttpResponseImpl> cf;
-        synchronized (response_cfs) {
-            if (!response_cfs.isEmpty()) {
-                cf = response_cfs.remove(0);
-            } else {
-                cf = new CompletableFuture<>();
-                response_cfs.add(cf);
-            }
-        }
-        PushGroup<?> pg = request.pushGroup();
-        if (pg != null) {
-            // if an error occurs make sure it is recorded in the PushGroup
-            cf = cf.whenComplete((t,e) -> pg.pushError(e));
-        }
-        return cf;
-    }
-
-    /**
-     * Completes the first uncompleted CF on list, and removes it. If there is no
-     * uncompleted CF then creates one (completes it) and adds to list
-     */
-    void completeResponse(HttpResponse r) {
-        HttpResponseImpl resp = (HttpResponseImpl)r;
-        synchronized (response_cfs) {
-            int cfs_len = response_cfs.size();
-            for (int i=0; i<cfs_len; i++) {
-                CompletableFuture<HttpResponseImpl> cf = response_cfs.get(i);
-                if (!cf.isDone()) {
-                    cf.complete(resp);
-                    response_cfs.remove(cf);
-                    return;
-                }
-            }
-            response_cfs.add(CompletableFuture.completedFuture(resp));
-        }
-    }
-
-    // methods to update state and remove stream when finished
-
-    synchronized void requestSent() {
-        requestSent = true;
-        if (responseReceived)
-            connection.deleteStream(this);
-    }
-
-    synchronized void responseReceived() {
-        responseReceived = true;
-        if (requestSent)
-            connection.deleteStream(this);
-        PushGroup<?> pg = request.pushGroup();
-        if (pg != null)
-            pg.noMorePushes();
-    }
-
-    /**
-     * same as above but for errors
-     *
-     * @param t
-     */
-    void completeResponseExceptionally(Throwable t) {
-        synchronized (response_cfs) {
-            for (CompletableFuture<HttpResponseImpl> cf : response_cfs) {
-                if (!cf.isDone()) {
-                    cf.completeExceptionally(t);
-                    response_cfs.remove(cf);
-                    return;
-                }
-            }
-            response_cfs.add(CompletableFuture.failedFuture(t));
-        }
-    }
-
-    void sendBodyImpl() throws IOException, InterruptedException {
-        if (requestContentLen == 0) {
-            // no body
-            requestSent();
-            return;
-        }
-        DataFrame df;
-        do {
-            df = getDataFrame();
-            // TODO: check accumulated content length (if not checked below)
-            connection.sendFrame(df);
-        } while (!df.getFlag(DataFrame.END_STREAM));
-        requestSent();
-    }
-
-    @Override
-    void cancel() {
-        cancelImpl(new Exception("Cancelled"));
-    }
-
-
-    void cancelImpl(Throwable e) {
-        Log.logTrace("cancelling stream: {0}\n", e.toString());
-        inputQ.close();
-        completeResponseExceptionally(e);
-        try {
-            connection.resetStream(streamid, ResetFrame.CANCEL);
-        } catch (IOException | InterruptedException ex) {
-            Log.logError(ex);
-        }
-    }
-
-    @Override
-    CompletableFuture<Void> sendRequestAsync() {
-        CompletableFuture<Void> cf = new CompletableFuture<>();
-        executor.execute(() -> {
-           try {
-               sendRequest();
-               cf.complete(null);
-           } catch (IOException |InterruptedException e) {
-               cf.completeExceptionally(e);
-           }
-        }, null);
-        return cf;
-    }
-
-    @Override
-    <T> T responseBody(HttpResponse.BodyProcessor<T> processor) throws IOException {
-        this.responseProcessor = processor;
-        T body = processor.onResponseBodyStart(
-                    responseContentLen, responseHeaders,
-                    responseFlowController); // TODO: filter headers
-        if (body == null) {
-            receiveData();
-            body = processor.onResponseComplete();
-        } else
-            receiveDataAsync(processor);
-        responseReceived();
-        return body;
-    }
-
-    // called from Http2Connection reader thread
-    synchronized void updateOutgoingWindow(int update) {
-        remoteRequestFlowController.accept(update);
-    }
-
-    void close(String msg) {
-        cancel();
-    }
-
-    static class PushedStream extends Stream {
-        final PushGroup<?> pushGroup;
-        final private Stream parent;      // used by server push streams
-        // push streams need the response CF allocated up front as it is
-        // given directly to user via the multi handler callback function.
-        final CompletableFuture<HttpResponseImpl> pushCF;
-        final HttpRequestImpl pushReq;
-
-        PushedStream(PushGroup<?> pushGroup, HttpClientImpl client,
-                Http2Connection connection, Stream parent,
-                HttpRequestImpl pushReq) {
-            super(client, connection, pushReq);
-            this.pushGroup = pushGroup;
-            this.pushReq = pushReq;
-            this.pushCF = new CompletableFuture<>();
-            this.parent = parent;
-        }
-
-        // Following methods call the super class but in case of
-        // error record it in the PushGroup. The error method is called
-        // with a null value when no error occurred (is a no-op)
-        @Override
-        CompletableFuture<Void> sendBodyAsync() {
-            return super.sendBodyAsync()
-                        .whenComplete((v, t) -> pushGroup.pushError(t));
-        }
-
-        @Override
-        CompletableFuture<Void> sendHeadersAsync() {
-            return super.sendHeadersAsync()
-                        .whenComplete((v, t) -> pushGroup.pushError(t));
-        }
-
-        @Override
-        CompletableFuture<Void> sendRequestAsync() {
-            return super.sendRequestAsync()
-                        .whenComplete((v, t) -> pushGroup.pushError(t));
-        }
-
-        @Override
-        CompletableFuture<HttpResponseImpl> getResponseAsync(Void vo) {
-            return pushCF.whenComplete((v, t) -> pushGroup.pushError(t));
-        }
-
-        @Override
-        <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
-            return super.responseBodyAsync(processor)
-                        .whenComplete((v, t) -> pushGroup.pushError(t));
-        }
-
-        @Override
-        void completeResponse(HttpResponse r) {
-            HttpResponseImpl resp = (HttpResponseImpl)r;
-            Utils.logResponse(resp);
-            pushCF.complete(resp);
-        }
-
-        @Override
-        void completeResponseExceptionally(Throwable t) {
-            pushCF.completeExceptionally(t);
-        }
-
-        @Override
-        synchronized void responseReceived() {
-            super.responseReceived();
-            pushGroup.pushCompleted();
-        }
-
-        // create and return the PushResponseImpl
-        @Override
-        protected void handleResponse() {
-            HttpConnection c = connection.connection; // TODO: improve
-            long statusCode = responseHeaders
-                .firstValueAsLong(":status")
-                .orElse(-1L);
-
-            if (statusCode == -1L)
-                completeResponseExceptionally(new IOException("No status code"));
-            ImmutableHeaders h = new ImmutableHeaders(responseHeaders, Utils.ALL_HEADERS);
-            this.response = new HttpResponseImpl((int)statusCode, pushReq, h, this,
-                c.sslParameters());
-            this.responseContentLen = responseHeaders
-                .firstValueAsLong("content-length")
-                .orElse(-1L);
-            // different implementations for normal streams and pushed streams
-            completeResponse(response);
-        }
-    }
-
-    /**
-     * One PushGroup object is associated with the parent Stream of
-     * the pushed Streams. This keeps track of all common state associated
-     * with the pushes.
-     */
-    static class PushGroup<T> {
-        // the overall completion object, completed when all pushes are done.
-        final CompletableFuture<T> resultCF;
-        Throwable error; // any exception that occured during pushes
-
-        // CF for main response
-        final CompletableFuture<HttpResponse> mainResponse;
-
-        // user's processor object
-        final HttpResponse.MultiProcessor<T> multiProcessor;
-
-        // per push handler function provided by processor
-        final private BiFunction<HttpRequest,
-                           CompletableFuture<HttpResponse>,
-                           Boolean> pushHandler;
-        int numberOfPushes;
-        int remainingPushes;
-        boolean noMorePushes = false;
-
-        PushGroup(HttpResponse.MultiProcessor<T> multiProcessor, HttpRequestImpl req) {
-            this.resultCF = new CompletableFuture<>();
-            this.mainResponse = new CompletableFuture<>();
-            this.multiProcessor = multiProcessor;
-            this.pushHandler = multiProcessor.onStart(req, mainResponse);
-        }
-
-        CompletableFuture<T> groupResult() {
-            return resultCF;
-        }
-
-        CompletableFuture<HttpResponse> mainResponse() {
-            return mainResponse;
-        }
-
-        private BiFunction<HttpRequest,
-            CompletableFuture<HttpResponse>, Boolean> pushHandler()
-        {
-                return pushHandler;
-        }
-
-        synchronized void addPush() {
-            numberOfPushes++;
-            remainingPushes++;
-        }
-
-        synchronized int numberOfPushes() {
-            return numberOfPushes;
-        }
-        // This is called when the main body response completes because it means
-        // no more PUSH_PROMISEs are possible
-        synchronized void noMorePushes() {
-            noMorePushes = true;
-            checkIfCompleted();
-        }
-
-        synchronized void pushCompleted() {
-            remainingPushes--;
-            checkIfCompleted();
-        }
-
-        synchronized void checkIfCompleted() {
-            if (remainingPushes == 0 && error == null && noMorePushes) {
-                T overallResult = multiProcessor.onComplete();
-                resultCF.complete(overallResult);
-            }
-        }
-
-        synchronized void pushError(Throwable t) {
-            if (t == null)
-                return;
-            this.error = t;
-            resultCF.completeExceptionally(t);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/TimeoutEvent.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-/**
- * Timeout event delivered by selector thread. Executes given handler
- * if the timer not cancelled first.
- *
- * Register with HttpClientImpl.registerTimer(TimeoutEvent)
- *
- * Cancel with HttpClientImpl.cancelTimer(TimeoutEvent)
- */
-abstract class TimeoutEvent {
-
-    final long timeval;
-
-    long delta; // used when on queue
-
-    TimeoutEvent(long timeval) { this.timeval = timeval; }
-
-    public abstract void handle();
-
-    /**  Returns the timevalue in milli-seconds */
-    public long timevalMillis() { return timeval; }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Utils.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 sun.net.NetProperties;
-
-import javax.net.ssl.SSLParameters;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.net.NetPermission;
-import java.net.URI;
-import java.net.URLPermission;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.LongBinaryOperator;
-import java.util.function.Predicate;
-
-/**
- * Miscellaneous utilities
- */
-final class Utils {
-
-    /**
-     * Allocated buffer size. Must never be higher than 16K. But can be lower
-     * if smaller allocation units preferred. HTTP/2 mandates that all
-     * implementations support frame payloads of at least 16K.
-     */
-    public static final int BUFSIZE = 16 * 1024;
-
-    private static final Set<String> DISALLOWED_HEADERS_SET = Set.of(
-            "authorization", "connection", "cookie", "content-length",
-            "date", "expect", "from", "host", "origin", "proxy-authorization",
-            "referer", "user-agent", "upgrade", "via", "warning");
-
-    static final Predicate<String>
-        ALLOWED_HEADERS = header -> !Utils.DISALLOWED_HEADERS_SET.contains(header);
-
-    static final Predicate<String>
-        ALL_HEADERS = header -> true;
-
-    static InetSocketAddress getAddress(HttpRequestImpl req) {
-        URI uri = req.uri();
-        if (uri == null) {
-            return req.authority();
-        }
-        int port = uri.getPort();
-        if (port == -1) {
-            if (uri.getScheme().equalsIgnoreCase("https")) {
-                port = 443;
-            } else {
-                port = 80;
-            }
-        }
-        String host = uri.getHost();
-        if (req.proxy() == null) {
-            return new InetSocketAddress(host, port);
-        } else {
-            return InetSocketAddress.createUnresolved(host, port);
-        }
-    }
-
-    /**
-     * Puts position to limit and limit to capacity so we can resume reading
-     * into this buffer, but if required > 0 then limit may be reduced so that
-     * no more than required bytes are read next time.
-     */
-    static void resumeChannelRead(ByteBuffer buf, int required) {
-        int limit = buf.limit();
-        buf.position(limit);
-        int capacity = buf.capacity() - limit;
-        if (required > 0 && required < capacity) {
-            buf.limit(limit + required);
-        } else {
-            buf.limit(buf.capacity());
-        }
-    }
-
-    private Utils() { }
-
-    /**
-     * Validates a RFC7230 token
-     */
-    static void validateToken(String token, String errormsg) {
-        int length = token.length();
-        for (int i = 0; i < length; i++) {
-            int c = token.codePointAt(i);
-            if (c >= 0x30 && c <= 0x39 // 0 - 9
-                    || (c >= 0x61 && c <= 0x7a) // a - z
-                    || (c >= 0x41 && c <= 0x5a) // A - Z
-                    || (c >= 0x21 && c <= 0x2e && c != 0x22 && c != 0x27 && c != 0x2c)
-                    || (c >= 0x5e && c <= 0x60)
-                    || (c == 0x7c) || (c == 0x7e)) {
-            } else {
-                throw new IllegalArgumentException(errormsg);
-            }
-        }
-    }
-
-    /**
-     * Returns the security permission required for the given details.
-     * If method is CONNECT, then uri must be of form "scheme://host:port"
-     */
-    static URLPermission getPermission(URI uri,
-                                       String method,
-                                       Map<String, List<String>> headers) {
-        StringBuilder sb = new StringBuilder();
-
-        String urlstring, actionstring;
-
-        if (method.equals("CONNECT")) {
-            urlstring = uri.toString();
-            actionstring = "CONNECT";
-        } else {
-            sb.append(uri.getScheme())
-                    .append("://")
-                    .append(uri.getAuthority())
-                    .append(uri.getPath());
-            urlstring = sb.toString();
-
-            sb = new StringBuilder();
-            sb.append(method);
-            if (headers != null && !headers.isEmpty()) {
-                sb.append(':');
-                Set<String> keys = headers.keySet();
-                boolean first = true;
-                for (String key : keys) {
-                    if (!first) {
-                        sb.append(',');
-                    }
-                    sb.append(key);
-                    first = false;
-                }
-            }
-            actionstring = sb.toString();
-        }
-        return new URLPermission(urlstring, actionstring);
-    }
-
-    static void checkNetPermission(String target) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm == null)
-            return;
-        NetPermission np = new NetPermission(target);
-        sm.checkPermission(np);
-    }
-
-    static int getIntegerNetProperty(String name, int defaultValue) {
-        return AccessController.doPrivileged((PrivilegedAction<Integer>) () ->
-                NetProperties.getInteger(name, defaultValue));
-    }
-
-    static String getNetProperty(String name) {
-        return AccessController.doPrivileged((PrivilegedAction<String>) () ->
-                NetProperties.get(name));
-    }
-
-    static SSLParameters copySSLParameters(SSLParameters p) {
-        SSLParameters p1 = new SSLParameters();
-        p1.setAlgorithmConstraints(p.getAlgorithmConstraints());
-        p1.setCipherSuites(p.getCipherSuites());
-        p1.setEnableRetransmissions(p.getEnableRetransmissions());
-        p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
-        p1.setMaximumPacketSize(p.getMaximumPacketSize());
-        p1.setNeedClientAuth(p.getNeedClientAuth());
-        String[] protocols = p.getProtocols();
-        if (protocols != null)
-            p1.setProtocols(protocols.clone());
-        p1.setSNIMatchers(p.getSNIMatchers());
-        p1.setServerNames(p.getServerNames());
-        p1.setUseCipherSuitesOrder(p.getUseCipherSuitesOrder());
-        p1.setWantClientAuth(p.getWantClientAuth());
-        return p1;
-    }
-
-    /**
-     * Set limit to position, and position to mark.
-     */
-    static void flipToMark(ByteBuffer buffer, int mark) {
-        buffer.limit(buffer.position());
-        buffer.position(mark);
-    }
-
-    static String stackTrace(Throwable t) {
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        String s = null;
-        try {
-            PrintStream p = new PrintStream(bos, true, "US-ASCII");
-            t.printStackTrace(p);
-            s = bos.toString("US-ASCII");
-        } catch (UnsupportedEncodingException ex) {
-            // can't happen
-        }
-        return s;
-    }
-
-    /**
-     * Copies as much of src to dst as possible.
-     */
-    static void copy(ByteBuffer src, ByteBuffer dst) {
-        int srcLen = src.remaining();
-        int dstLen = dst.remaining();
-        if (srcLen > dstLen) {
-            int diff = srcLen - dstLen;
-            int limit = src.limit();
-            src.limit(limit - diff);
-            dst.put(src);
-            src.limit(limit);
-        } else {
-            dst.put(src);
-        }
-    }
-
-    static ByteBuffer copy(ByteBuffer src) {
-        ByteBuffer dst = ByteBuffer.allocate(src.remaining());
-        dst.put(src);
-        dst.flip();
-        return dst;
-    }
-
-    //
-    // Helps to trim long names (packages, nested/inner types) in logs/toString
-    //
-    static String toStringSimple(Object o) {
-        return o.getClass().getSimpleName() + "@" +
-                Integer.toHexString(System.identityHashCode(o));
-    }
-
-    //
-    // 1. It adds a number of remaining bytes;
-    // 2. Standard Buffer-type toString for CharBuffer (since it adheres to the
-    // contract of java.lang.CharSequence.toString() which is both not too
-    // useful and not too private)
-    //
-    static String toString(Buffer b) {
-        return toStringSimple(b)
-                + "[pos=" + b.position()
-                + " lim=" + b.limit()
-                + " cap=" + b.capacity()
-                + " rem=" + b.remaining() + "]";
-    }
-
-    static String toString(CharSequence s) {
-        return s == null
-                ? "null"
-                : toStringSimple(s) + "[len=" + s.length() + "]";
-    }
-
-    static String dump(Object... objects) {
-        return Arrays.toString(objects);
-    }
-
-    static final System.Logger logger = System.getLogger("java.net.http.WebSocket");
-
-    static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
-
-    static String webSocketSpecViolation(String section, String detail) {
-        return "RFC 6455 " + section + " " + detail;
-    }
-
-    static void logResponse(HttpResponseImpl r) {
-        if (!Log.requests()) {
-            return;
-        }
-        StringBuilder sb = new StringBuilder();
-        String method = r.request().method();
-        URI uri = r.uri();
-        String uristring = uri == null ? "" : uri.toString();
-        sb.append('(').append(method).append(" ").append(uristring).append(") ").append(Integer.toString(r.statusCode()));
-        Log.logResponse(sb.toString());
-    }
-
-    static int remaining(ByteBuffer[] bufs) {
-        int remain = 0;
-        for (ByteBuffer buf : bufs)
-            remain += buf.remaining();
-        return remain;
-    }
-
-    // assumes buffer was written into starting at position zero
-    static void unflip(ByteBuffer buf) {
-        buf.position(buf.limit());
-        buf.limit(buf.capacity());
-    }
-
-    static void close(Closeable... chans) {
-        for (Closeable chan : chans) {
-            try {
-                chan.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    static ByteBuffer[] reduce(ByteBuffer[] bufs, int start, int number) {
-        if (start == 0 && number == bufs.length)
-            return bufs;
-        ByteBuffer[] nbufs = new ByteBuffer[number];
-        int j = 0;
-        for (int i=start; i<start+number; i++)
-            nbufs[j++] = bufs[i];
-        return nbufs;
-    }
-
-    static String asString(ByteBuffer buf) {
-        byte[] b = new byte[buf.remaining()];
-        buf.get(b);
-        return new String(b, StandardCharsets.US_ASCII);
-    }
-
-    // Put all these static 'empty' singletons here
-    @SuppressWarnings("rawtypes")
-    static CompletableFuture[] EMPTY_CFARRAY = new CompletableFuture[0];
-
-    static ByteBuffer EMPTY_BYTEBUFFER = ByteBuffer.allocate(0);
-    static ByteBuffer[] EMPTY_BB_ARRAY = new ByteBuffer[0];
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WS.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 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(this, executor, channel, errorHandler);
-        receiver = new WSReceiver(this.listener, this, executor, channel);
-    }
-
-    private void start() {
-        receiver.start();
-    }
-
-    @Override
-    public CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast) {
-        requireNonNull(message, "message");
-        synchronized (stateLock) {
-            checkState();
-            return transmitter.sendText(message, isLast);
-        }
-    }
-
-    @Override
-    public CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast) {
-        requireNonNull(message, "message");
-        synchronized (stateLock) {
-            checkState();
-            return transmitter.sendBinary(message, isLast);
-        }
-    }
-
-    @Override
-    public CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
-        requireNonNull(message, "message");
-        synchronized (stateLock) {
-            checkState();
-            return transmitter.sendPing(message);
-        }
-    }
-
-    @Override
-    public CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
-        requireNonNull(message, "message");
-        synchronized (stateLock) {
-            checkState();
-            return transmitter.sendPong(message);
-        }
-    }
-
-    @Override
-    public CompletableFuture<WebSocket> sendClose(CloseCode code, CharSequence reason) {
-        requireNonNull(code, "code");
-        requireNonNull(reason, "reason");
-        synchronized (stateLock) {
-            return doSendClose(() -> transmitter.sendClose(code, reason));
-        }
-    }
-
-    @Override
-    public CompletableFuture<WebSocket> sendClose() {
-        synchronized (stateLock) {
-            return doSendClose(() -> transmitter.sendClose());
-        }
-    }
-
-    private CompletableFuture<WebSocket> doSendClose(Supplier<CompletableFuture<WebSocket>> s) {
-        checkState();
-        boolean closeChannel = false;
-        synchronized (stateLock) {
-            if (state == State.CLOSED_REMOTELY) {
-                closeChannel = tryChangeState(State.CLOSED);
-            } else {
-                tryChangeState(State.CLOSED_LOCALLY);
-            }
-        }
-        CompletableFuture<WebSocket> 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 void request(long n) {
-        if (n < 0L) {
-            throw new IllegalArgumentException("The number must not be negative: " + n);
-        }
-        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, CharSequence 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;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSBuilder.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.time.Duration;
-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 Duration timeout;
-
-    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(Duration timeout) {
-        this.timeout = requireNonNull(timeout, "timeout");
-        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);
-    }
-
-    Duration getConnectTimeout() { return timeout; }
-
-    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);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSCharsetToolkit.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSDisposable.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-
-interface WSDisposable {
-
-    void dispose();
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,487 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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));
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 == MessagePart.WHOLE || part == MessagePart.LAST);
-                } 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, 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));
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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;
-import java.nio.CharBuffer;
-
-interface WSMessageConsumer {
-
-    void onText(MessagePart part, WSShared<CharBuffer> data);
-
-    void onBinary(MessagePart part, WSShared<ByteBuffer> data);
-
-    void onPing(WSShared<ByteBuffer> data);
-
-    void onPong(WSShared<ByteBuffer> data);
-
-    void onClose(CloseCode code, CharSequence reason);
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageSender.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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.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(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);
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.UncheckedIOException;
-import java.io.IOException;
-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.time.Duration;
-import java.time.temporal.ChronoUnit;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-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);
-        Duration connectTimeout = b.getConnectTimeout();
-        if (connectTimeout != null) {
-            requestBuilder.timeout(
-                    TimeUnit.of(ChronoUnit.MILLIS),
-                    connectTimeout.get(ChronoUnit.MILLIS)
-            );
-        }
-        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);
-                    } catch (UncheckedIOException ee) {
-                        return CompletableFuture.failedFuture(ee.getCause());
-                    }
-                });
-    }
-
-    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 = null;
-        try {
-            channel = ((HttpResponseImpl) response).rawChannel();
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-        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;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSOutgoingMessage.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-abstract class WSOutgoingMessage {
-
-    interface Visitor {
-        void visit(Text 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 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) + "]";
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSProtocolException.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 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 + "]";
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.CharBuffer;
-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.RawEvent 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);
-                }
-            }
-        }
-    }
-
-    void request(long n) {
-        long newDemand = demand.accumulateAndGet(n, (p, i) -> p + i < 0 ? Long.MAX_VALUE : p + i);
-        handler.signal();
-        assert newDemand >= 0 : 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, WSShared<CharBuffer> data) {
-            decrementDemand();
-            CompletionStage<?> cs;
-            try {
-                cs = listener.onText(webSocket, data.buffer(), 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.RawEvent createChannelEvent() {
-        return new RawChannel.RawEvent() {
-
-            @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 + "]";
-            }
-        };
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSShared.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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");
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSSharedPool.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package 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 + "]]";
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSSignalHandler.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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.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 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<WebSocket>>>
-            backlog = new LinkedBlockingQueue<>();
-    private final WSMessageSender sender;
-    private final WSSignalHandler handler;
-    private final WebSocket webSocket;
-    private boolean previousMessageSent = true;
-    private boolean canSendBinary = true;
-    private boolean canSendText = true;
-
-    WSTransmitter(WebSocket ws, Executor executor, RawChannel channel, Consumer<Throwable> errorHandler) {
-        this.webSocket = ws;
-        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<WebSocket> sendText(CharSequence message, boolean isLast) {
-        checkAndUpdateText(isLast);
-        return acceptMessage(new Text(isLast, message));
-    }
-
-    CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast) {
-        checkAndUpdateBinary(isLast);
-        return acceptMessage(new Binary(isLast, message));
-    }
-
-    CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
-        checkSize(message.remaining(), 125);
-        return acceptMessage(new Ping(message));
-    }
-
-    CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
-        checkSize(message.remaining(), 125);
-        return acceptMessage(new Pong(message));
-    }
-
-    CompletableFuture<WebSocket> sendClose(WebSocket.CloseCode code, CharSequence reason) {
-        return acceptMessage(createCloseMessage(code, reason));
-    }
-
-    CompletableFuture<WebSocket> sendClose() {
-        return acceptMessage(new Close(ByteBuffer.allocate(0)));
-    }
-
-    private CompletableFuture<WebSocket> acceptMessage(WSOutgoingMessage m) {
-        CompletableFuture<WebSocket> 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<WebSocket>> p = backlog.peek();
-                boolean sent = sender.trySendFully(p.first);
-                if (sent) {
-                    backlog.remove();
-                    p.second.complete(webSocket);
-                    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;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSUtils.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.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.RawEvent 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.RawEvent createHandler() {
-        return new RawChannel.RawEvent() {
-
-            @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 + "]";
-            }
-        };
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1068 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.time.Duration;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionStage;
-
-/**
- * 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}. Otherwise, invoke {@link #abort() abort} to close abruptly.
- *
- * <p> Once closed the {@code WebSocket} remains closed and 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 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> 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.
- *
- * @implNote The default implementation's methods do not block before returning
- * a {@code CompletableFuture}.
- *
- * @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
-         * amount of time then {@link #buildAsync()} completes exceptionally
-         * with a {@code HttpTimeoutException}.
-         *
-         * <p> If this method is not invoked then the timeout is deemed infinite.
-         *
-         * @param timeout
-         *         the timeout
-         *
-         * @return this builder
-         */
-        Builder connectTimeout(Duration timeout);
-
-        /**
-         * Builds a {@code WebSocket}.
-         *
-         * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
-         * normally 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} with the {@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, CharSequence, 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}.
-         *
-         * @implNote This implementation passes only complete UTF-16 sequences
-         * to the {@code onText} method.
-         *
-         * @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,
-                                          CharSequence 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 status 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 {@code sendX} methods are reported to
-         * the {@code CompletableFuture} these methods 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} in cases where a partial
-     * message may be received.
-     *
-     * @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 consisting of a single part.
-         */
-        WHOLE
-    }
-
-    /**
-     * Sends a Text message with characters from the given {@code CharSequence}.
-     *
-     * <p> Returns a {@code CompletableFuture<WebSocket>} 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
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation;
-     *          or if a previous Binary message was not sent with {@code isLast == true}
-     * </ul>
-     *
-     * @implNote This implementation does not accept partial UTF-16
-     * sequences. In case such a sequence is passed, a returned {@code
-     * CompletableFuture} completes exceptionally.
-     *
-     * @param message
-     *         the message
-     * @param isLast
-     *         {@code true} if this is the last part of the message,
-     *         {@code false} otherwise
-     *
-     * @return a CompletableFuture with this WebSocket
-     *
-     * @throws IllegalArgumentException
-     *         if {@code message} is a malformed (or an incomplete) UTF-16 sequence
-     */
-    CompletableFuture<WebSocket> 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 a {@code CompletableFuture<WebSocket>} 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
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation;
-     *          or if a previous Binary message was not sent with {@code isLast == true}
-     * </ul>
-     *
-     * @param message
-     *         the message
-     *
-     * @return a CompletableFuture with this WebSocket
-     *
-     * @throws IllegalArgumentException
-     *         if {@code message} is a malformed (or an incomplete) UTF-16 sequence
-     */
-    default CompletableFuture<WebSocket> sendText(CharSequence message) {
-        return sendText(message, true);
-    }
-
-    /**
-     * Sends a Binary message with bytes from the given {@code ByteBuffer}.
-     *
-     * <p> Returns a {@code CompletableFuture<WebSocket>} 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
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation;
-     *          or if a previous Text message was not sent with {@code isLast == true}
-     * </ul>
-     *
-     * @param message
-     *         the message
-     * @param isLast
-     *         {@code true} if this is the last part of the message,
-     *         {@code false} otherwise
-     *
-     * @return a CompletableFuture with this WebSocket
-     */
-    CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast);
-
-    /**
-     * Sends a Ping message.
-     *
-     * <p> Returns a {@code CompletableFuture<WebSocket>} 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
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation
-     * </ul>
-     *
-     * @param message
-     *         the message
-     *
-     * @return a CompletableFuture with this WebSocket
-     *
-     * @throws IllegalArgumentException
-     *         if {@code message.remaining() > 125}
-     */
-    CompletableFuture<WebSocket> sendPing(ByteBuffer message);
-
-    /**
-     * Sends a Pong message.
-     *
-     * <p> Returns a {@code CompletableFuture<WebSocket>} 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
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation
-     * </ul>
-     *
-     * @param message
-     *         the message
-     *
-     * @return a CompletableFuture with this WebSocket
-     *
-     * @throws IllegalArgumentException
-     *         if {@code message.remaining() > 125}
-     */
-    CompletableFuture<WebSocket> sendPong(ByteBuffer message);
-
-    /**
-     * Sends a Close message with the given close code and the reason.
-     *
-     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
-     * normally when the message has been sent or completes exceptionally if an
-     * error occurs.
-     *
-     * <p> A Close message may consist of a status code and a reason for
-     * closing. The reason must 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> The returned {@code CompletableFuture} can complete exceptionally
-     * with:
-     * <ul>
-     * <li> {@link IOException}
-     *          if an I/O error occurs during this operation
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation
-     * </ul>
-     *
-     * @param code
-     *         the close code
-     * @param reason
-     *         the reason; can be empty
-     *
-     * @return a CompletableFuture with this WebSocket
-     *
-     * @throws IllegalArgumentException
-     *         if {@code reason} doesn't have an UTF-8 representation not longer
-     *         than {@code 123} bytes
-     */
-    CompletableFuture<WebSocket> sendClose(CloseCode code, CharSequence reason);
-
-    /**
-     * Sends an empty Close message.
-     *
-     * <p> Returns a {@code CompletableFuture<WebSocket>} 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
-     * <li> {@link IllegalStateException}
-     *          if the {@code WebSocket} closes while this operation is in progress;
-     *          or if a Close message has been sent already;
-     *          or if there is an outstanding send operation
-     * </ul>
-     *
-     * @return a CompletableFuture with this WebSocket
-     */
-    CompletableFuture<WebSocket> sendClose();
-
-    /**
-     * Allows {@code n} more messages to be received by the {@link Listener
-     * Listener}.
-     *
-     * <p> The actual number of received messages might be fewer if a Close
-     * message is received, the connection closes 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}.
-     *
-     * @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, this 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}
-     */
-    void 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/jdk/src/java.httpclient/share/classes/java/net/http/WebSocketHandshakeException.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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/WindowUpdateFrame.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.nio.ByteBuffer;
-
-class WindowUpdateFrame extends Http2Frame {
-
-    int windowUpdate;
-
-    WindowUpdateFrame() {
-        type = TYPE;
-    }
-
-    public final static int TYPE = 0x8;
-
-    public void setUpdate(int windowUpdate) {
-        this.windowUpdate = windowUpdate;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(super.toString())
-          .append(" WindowUpdate: ")
-          .append(windowUpdate);
-        return sb.toString();
-    }
-
-    public int getUpdate() {
-        return this.windowUpdate;
-    }
-
-    /**
-     */
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        if (length != 4) {
-            throw new IOException("Invalid WindowUpdate frame");
-        }
-        windowUpdate = bc.getInt() & 0x7fffffff;
-    }
-
-    @Override
-    void computeLength() {
-        length = 4;
-    }
-
-    @Override
-    void writeOutgoing(ByteBufferGenerator bg) {
-        super.writeOutgoing(bg);
-        ByteBuffer buf = bg.getBuffer(4);
-        buf.putInt(windowUpdate);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/package-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-/**
- * <h2>High level HTTP and WebSocket API</h2>
- * This provides a high-level client interfaces to HTTP (versions 1.1 and 2)
- * and WebSocket. Synchronous and asynchronous (via {@link
- * java.util.concurrent.CompletableFuture}) modes are provided for HTTP.
- * WebSocket works in asynchronous mode only. The main types defined are:
- * <ul>
- *    <li>{@link java.net.http.HttpClient}</li>
- *    <li>{@link java.net.http.HttpRequest}</li>
- *    <li>{@link java.net.http.HttpResponse}</li>
- *    <li>{@link java.net.http.WebSocket}</li>
- * </ul>
- *
- * @since 9
- */
-package java.net.http;
--- a/jdk/src/java.httpclient/share/classes/module-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-/**
- * Defines the high-level HTTP and WebSocket API.
- */
-module java.httpclient {
-    requires java.base;
-    exports java.net.http;
-}
-
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BinaryRepresentationWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-
-interface BinaryRepresentationWriter {
-
-    boolean write(HeaderTable table, ByteBuffer destination);
-
-    BinaryRepresentationWriter reset();
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BulkSizeUpdateWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-
-import static java.util.Objects.requireNonNull;
-
-final class BulkSizeUpdateWriter implements BinaryRepresentationWriter {
-
-    private final SizeUpdateWriter writer = new SizeUpdateWriter();
-    private Iterator<Integer> maxSizes;
-    private boolean writing;
-    private boolean configured;
-
-    BulkSizeUpdateWriter maxHeaderTableSizes(Iterable<Integer> sizes) {
-        if (configured) {
-            throw new IllegalStateException("Already configured");
-        }
-        requireNonNull(sizes, "sizes");
-        maxSizes = sizes.iterator();
-        configured = true;
-        return this;
-    }
-
-    @Override
-    public boolean write(HeaderTable table, ByteBuffer destination) {
-        if (!configured) {
-            throw new IllegalStateException("Configure first");
-        }
-        while (true) {
-            if (writing) {
-                if (!writer.write(table, destination)) {
-                    return false;
-                }
-                writing = false;
-            } else if (maxSizes.hasNext()) {
-                writing = true;
-                writer.reset();
-                writer.maxHeaderTableSize(maxSizes.next());
-            } else {
-                configured = false;
-                return true;
-            }
-        }
-    }
-
-    @Override
-    public BulkSizeUpdateWriter reset() {
-        maxSizes = null;
-        writing = false;
-        configured = false;
-        return this;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Decoder.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,506 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.net.ProtocolException;
-import java.nio.ByteBuffer;
-
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-
-/**
- * Decodes headers from their binary representation.
- *
- * <p>Typical lifecycle looks like this:
- *
- * <p> {@link #Decoder(int) new Decoder}
- * ({@link #setMaxCapacity(int) setMaxCapacity}?
- * {@link #decode(ByteBuffer, boolean, DecodingCallback) decode})*
- *
- * @apiNote
- *
- * <p> The design intentions behind Decoder were to facilitate flexible and
- * incremental style of processing.
- *
- * <p> {@code Decoder} does not require a complete header block in a single
- * {@code ByteBuffer}. The header block can be spread across many buffers of any
- * size and decoded one-by-one the way it makes most sense for the user. This
- * way also allows not to limit the size of the header block.
- *
- * <p> Headers are delivered to the {@linkplain DecodingCallback callback} as
- * soon as they become decoded. Using the callback also gives the user a freedom
- * to decide how headers are processed. The callback does not limit the number
- * of headers decoded during single decoding operation.
- *
- * @since 9
- */
-public final class Decoder {
-
-    private static final State[] states = new State[256];
-
-    static {
-        // To be able to do a quick lookup, each of 256 possibilities are mapped
-        // to corresponding states.
-        //
-        // We can safely do this since patterns 1, 01, 001, 0001, 0000 are
-        // Huffman prefixes and therefore are inherently not ambiguous.
-        //
-        // I do it mainly for better debugging (to not go each time step by step
-        // through if...else tree). As for performance win for the decoding, I
-        // believe is negligible.
-        for (int i = 0; i < states.length; i++) {
-            if ((i & 0b1000_0000) == 0b1000_0000) {
-                states[i] = State.INDEXED;
-            } else if ((i & 0b1100_0000) == 0b0100_0000) {
-                states[i] = State.LITERAL_WITH_INDEXING;
-            } else if ((i & 0b1110_0000) == 0b0010_0000) {
-                states[i] = State.SIZE_UPDATE;
-            } else if ((i & 0b1111_0000) == 0b0001_0000) {
-                states[i] = State.LITERAL_NEVER_INDEXED;
-            } else if ((i & 0b1111_0000) == 0b0000_0000) {
-                states[i] = State.LITERAL;
-            } else {
-                throw new InternalError(String.valueOf(i));
-            }
-        }
-    }
-
-    private final HeaderTable table;
-
-    private State state = State.READY;
-    private final IntegerReader integerReader;
-    private final StringReader stringReader;
-    private final StringBuilder name;
-    private final StringBuilder value;
-    private int intValue;
-    private boolean firstValueRead;
-    private boolean firstValueIndex;
-    private boolean nameHuffmanEncoded;
-    private boolean valueHuffmanEncoded;
-    private int capacity;
-
-    /**
-     * Constructs a {@code Decoder} with the specified initial capacity of the
-     * header table.
-     *
-     * <p> The value has to be agreed between decoder and encoder out-of-band,
-     * e.g. by a protocol that uses HPACK (see <a
-     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
-     * Size</a>).
-     *
-     * @param capacity
-     *         a non-negative integer
-     *
-     * @throws IllegalArgumentException
-     *         if capacity is negative
-     */
-    public Decoder(int capacity) {
-        setMaxCapacity(capacity);
-        table = new HeaderTable(capacity);
-        integerReader = new IntegerReader();
-        stringReader = new StringReader();
-        name = new StringBuilder(512);
-        value = new StringBuilder(1024);
-    }
-
-    /**
-     * Sets a maximum capacity of the header table.
-     *
-     * <p> The value has to be agreed between decoder and encoder out-of-band,
-     * e.g. by a protocol that uses HPACK (see <a
-     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
-     * Size</a>).
-     *
-     * @param capacity
-     *         a non-negative integer
-     *
-     * @throws IllegalArgumentException
-     *         if capacity is negative
-     */
-    public void setMaxCapacity(int capacity) {
-        if (capacity < 0) {
-            throw new IllegalArgumentException("capacity >= 0: " + capacity);
-        }
-        // FIXME: await capacity update if less than what was prior to it
-        this.capacity = capacity;
-    }
-
-    /**
-     * Decodes a header block from the given buffer to the given callback.
-     *
-     * <p> Suppose a header block is represented by a sequence of {@code
-     * ByteBuffer}s in the form of {@code Iterator<ByteBuffer>}. And the
-     * consumer of decoded headers is represented by the callback. Then to
-     * decode the header block, the following approach might be used:
-     *
-     * <pre>{@code
-     * while (buffers.hasNext()) {
-     *     ByteBuffer input = buffers.next();
-     *     decoder.decode(input, callback, !buffers.hasNext());
-     * }
-     * }</pre>
-     *
-     * <p> The decoder reads as much as possible of the header block from the
-     * given buffer, starting at the buffer's position, and increments its
-     * position to reflect the bytes read. The buffer's mark and limit will not
-     * be modified.
-     *
-     * <p> Once the method is invoked with {@code endOfHeaderBlock == true}, the
-     * current header block is deemed ended, and inconsistencies, if any, are
-     * reported immediately by throwing an {@code UncheckedIOException}.
-     *
-     * <p> Each callback method is called only after the implementation has
-     * processed the corresponding bytes. If the bytes revealed a decoding
-     * error, the callback method is not called.
-     *
-     * <p> In addition to exceptions thrown directly by the method, any
-     * exceptions thrown from the {@code callback} will bubble up.
-     *
-     * @apiNote The method asks for {@code endOfHeaderBlock} flag instead of
-     * returning it for two reasons. The first one is that the user of the
-     * decoder always knows which chunk is the last. The second one is to throw
-     * the most detailed exception possible, which might be useful for
-     * diagnosing issues.
-     *
-     * @implNote This implementation is not atomic in respect to decoding
-     * errors. In other words, if the decoding operation has thrown a decoding
-     * error, the decoder is no longer usable.
-     *
-     * @param headerBlock
-     *         the chunk of the header block, may be empty
-     * @param endOfHeaderBlock
-     *         true if the chunk is the final (or the only one) in the sequence
-     *
-     * @param consumer
-     *         the callback
-     * @throws UncheckedIOException
-     *         in case of a decoding error
-     * @throws NullPointerException
-     *         if either headerBlock or consumer are null
-     */
-    public void decode(ByteBuffer headerBlock, boolean endOfHeaderBlock,
-                       DecodingCallback consumer) {
-        requireNonNull(headerBlock, "headerBlock");
-        requireNonNull(consumer, "consumer");
-        while (headerBlock.hasRemaining()) {
-            proceed(headerBlock, consumer);
-        }
-        if (endOfHeaderBlock && state != State.READY) {
-            throw new UncheckedIOException(
-                    new ProtocolException("Unexpected end of header block"));
-        }
-    }
-
-    private void proceed(ByteBuffer input, DecodingCallback action) {
-        switch (state) {
-            case READY:
-                resumeReady(input);
-                break;
-            case INDEXED:
-                resumeIndexed(input, action);
-                break;
-            case LITERAL:
-                resumeLiteral(input, action);
-                break;
-            case LITERAL_WITH_INDEXING:
-                resumeLiteralWithIndexing(input, action);
-                break;
-            case LITERAL_NEVER_INDEXED:
-                resumeLiteralNeverIndexed(input, action);
-                break;
-            case SIZE_UPDATE:
-                resumeSizeUpdate(input, action);
-                break;
-            default:
-                throw new InternalError(
-                        "Unexpected decoder state: " + String.valueOf(state));
-        }
-    }
-
-    private void resumeReady(ByteBuffer input) {
-        int b = input.get(input.position()) & 0xff; // absolute read
-        State s = states[b];
-        switch (s) {
-            case INDEXED:
-                integerReader.configure(7);
-                state = State.INDEXED;
-                firstValueIndex = true;
-                break;
-            case LITERAL:
-                state = State.LITERAL;
-                firstValueIndex = (b & 0b0000_1111) != 0;
-                if (firstValueIndex) {
-                    integerReader.configure(4);
-                }
-                break;
-            case LITERAL_WITH_INDEXING:
-                state = State.LITERAL_WITH_INDEXING;
-                firstValueIndex = (b & 0b0011_1111) != 0;
-                if (firstValueIndex) {
-                    integerReader.configure(6);
-                }
-                break;
-            case LITERAL_NEVER_INDEXED:
-                state = State.LITERAL_NEVER_INDEXED;
-                firstValueIndex = (b & 0b0000_1111) != 0;
-                if (firstValueIndex) {
-                    integerReader.configure(4);
-                }
-                break;
-            case SIZE_UPDATE:
-                integerReader.configure(5);
-                state = State.SIZE_UPDATE;
-                firstValueIndex = true;
-                break;
-            default:
-                throw new InternalError(String.valueOf(s));
-        }
-        if (!firstValueIndex) {
-            input.get(); // advance, next stop: "String Literal"
-        }
-    }
-
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 1 |        Index (7+)         |
-    //            +---+---------------------------+
-    //
-    private void resumeIndexed(ByteBuffer input, DecodingCallback action) {
-        if (!integerReader.read(input)) {
-            return;
-        }
-        intValue = integerReader.get();
-        integerReader.reset();
-        try {
-            HeaderTable.HeaderField f = table.get(intValue);
-            action.onIndexed(intValue, f.name, f.value);
-        } finally {
-            state = State.READY;
-        }
-    }
-
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 0 | 0 | 0 |  Index (4+)   |
-    //            +---+---+-----------------------+
-    //            | H |     Value Length (7+)     |
-    //            +---+---------------------------+
-    //            | Value String (Length octets)  |
-    //            +-------------------------------+
-    //
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 0 | 0 | 0 |       0       |
-    //            +---+---+-----------------------+
-    //            | H |     Name Length (7+)      |
-    //            +---+---------------------------+
-    //            |  Name String (Length octets)  |
-    //            +---+---------------------------+
-    //            | H |     Value Length (7+)     |
-    //            +---+---------------------------+
-    //            | Value String (Length octets)  |
-    //            +-------------------------------+
-    //
-    private void resumeLiteral(ByteBuffer input, DecodingCallback action) {
-        if (!completeReading(input)) {
-            return;
-        }
-        try {
-            if (firstValueIndex) {
-                HeaderTable.HeaderField f = table.get(intValue);
-                action.onLiteral(intValue, f.name, value, valueHuffmanEncoded);
-            } else {
-                action.onLiteral(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
-            }
-        } finally {
-            cleanUpAfterReading();
-        }
-    }
-
-    //
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 1 |      Index (6+)       |
-    //            +---+---+-----------------------+
-    //            | H |     Value Length (7+)     |
-    //            +---+---------------------------+
-    //            | Value String (Length octets)  |
-    //            +-------------------------------+
-    //
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 1 |           0           |
-    //            +---+---+-----------------------+
-    //            | H |     Name Length (7+)      |
-    //            +---+---------------------------+
-    //            |  Name String (Length octets)  |
-    //            +---+---------------------------+
-    //            | H |     Value Length (7+)     |
-    //            +---+---------------------------+
-    //            | Value String (Length octets)  |
-    //            +-------------------------------+
-    //
-    private void resumeLiteralWithIndexing(ByteBuffer input, DecodingCallback action) {
-        if (!completeReading(input)) {
-            return;
-        }
-        try {
-            //
-            // 1. (name, value) will be stored in the table as strings
-            // 2. Most likely the callback will also create strings from them
-            // ------------------------------------------------------------------------
-            //    Let's create those string beforehand (and only once!) to benefit everyone
-            //
-            String n;
-            String v = value.toString();
-            if (firstValueIndex) {
-                HeaderTable.HeaderField f = table.get(intValue);
-                n = f.name;
-                action.onLiteralWithIndexing(intValue, n, v, valueHuffmanEncoded);
-            } else {
-                n = name.toString();
-                action.onLiteralWithIndexing(n, nameHuffmanEncoded, v, valueHuffmanEncoded);
-            }
-            table.put(n, v);
-        } catch (IllegalArgumentException | IllegalStateException e) {
-            throw new UncheckedIOException(
-                    (IOException) new ProtocolException().initCause(e));
-        } finally {
-            cleanUpAfterReading();
-        }
-    }
-
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 0 | 0 | 1 |  Index (4+)   |
-    //            +---+---+-----------------------+
-    //            | H |     Value Length (7+)     |
-    //            +---+---------------------------+
-    //            | Value String (Length octets)  |
-    //            +-------------------------------+
-    //
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 0 | 0 | 1 |       0       |
-    //            +---+---+-----------------------+
-    //            | H |     Name Length (7+)      |
-    //            +---+---------------------------+
-    //            |  Name String (Length octets)  |
-    //            +---+---------------------------+
-    //            | H |     Value Length (7+)     |
-    //            +---+---------------------------+
-    //            | Value String (Length octets)  |
-    //            +-------------------------------+
-    //
-    private void resumeLiteralNeverIndexed(ByteBuffer input, DecodingCallback action) {
-        if (!completeReading(input)) {
-            return;
-        }
-        try {
-            if (firstValueIndex) {
-                HeaderTable.HeaderField f = table.get(intValue);
-                action.onLiteralNeverIndexed(intValue, f.name, value, valueHuffmanEncoded);
-            } else {
-                action.onLiteralNeverIndexed(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
-            }
-        } finally {
-            cleanUpAfterReading();
-        }
-    }
-
-    //              0   1   2   3   4   5   6   7
-    //            +---+---+---+---+---+---+---+---+
-    //            | 0 | 0 | 1 |   Max size (5+)   |
-    //            +---+---------------------------+
-    //
-    private void resumeSizeUpdate(ByteBuffer input, DecodingCallback action) {
-        if (!integerReader.read(input)) {
-            return;
-        }
-        intValue = integerReader.get();
-        assert intValue >= 0;
-        if (intValue > capacity) {
-            throw new UncheckedIOException(new ProtocolException(
-                    format("Received capacity exceeds expected: " +
-                            "capacity=%s, expected=%s", intValue, capacity)));
-        }
-        integerReader.reset();
-        try {
-            action.onSizeUpdate(intValue);
-            table.setMaxSize(intValue);
-        } finally {
-            state = State.READY;
-        }
-    }
-
-    private boolean completeReading(ByteBuffer input) {
-        if (!firstValueRead) {
-            if (firstValueIndex) {
-                if (!integerReader.read(input)) {
-                    return false;
-                }
-                intValue = integerReader.get();
-                integerReader.reset();
-            } else {
-                if (!stringReader.read(input, name)) {
-                    return false;
-                }
-                nameHuffmanEncoded = stringReader.isHuffmanEncoded();
-                stringReader.reset();
-            }
-            firstValueRead = true;
-            return false;
-        } else {
-            if (!stringReader.read(input, value)) {
-                return false;
-            }
-        }
-        valueHuffmanEncoded = stringReader.isHuffmanEncoded();
-        stringReader.reset();
-        return true;
-    }
-
-    private void cleanUpAfterReading() {
-        name.setLength(0);
-        value.setLength(0);
-        firstValueRead = false;
-        state = State.READY;
-    }
-
-    private enum State {
-        READY,
-        INDEXED,
-        LITERAL_NEVER_INDEXED,
-        LITERAL,
-        LITERAL_WITH_INDEXING,
-        SIZE_UPDATE
-    }
-
-    HeaderTable getTable() {
-        return table;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/DecodingCallback.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-
-/**
- * Delivers results of the {@link Decoder#decode(ByteBuffer, boolean,
- * DecodingCallback) decoding operation}.
- *
- * <p> Methods of the callback are never called by a decoder with any of the
- * arguments being {@code null}.
- *
- * @apiNote
- *
- * <p> The callback provides methods for all possible <a
- * href="https://tools.ietf.org/html/rfc7541#section-6">binary
- * representations</a>. This could be useful for implementing an intermediary,
- * logging, debugging, etc.
- *
- * <p> The callback is an interface in order to interoperate with lambdas (in
- * the most common use case):
- * <pre>{@code
- *     DecodingCallback callback = (name, value) -> System.out.println(name + ", " + value);
- * }</pre>
- *
- * <p> Names and values are {@link CharSequence}s rather than {@link String}s in
- * order to allow users to decide whether or not they need to create objects. A
- * {@code CharSequence} might be used in-place, for example, to be appended to
- * an {@link Appendable} (e.g. {@link StringBuilder}) and then discarded.
- *
- * <p> That said, if a passed {@code CharSequence} needs to outlast the method
- * call, it needs to be copied.
- *
- * @since 9
- */
-@FunctionalInterface
-public interface DecodingCallback {
-
-    /**
-     * A method the more specific methods of the callback forward their calls
-     * to.
-     *
-     * @param name
-     *         header name
-     * @param value
-     *         header value
-     */
-    void onDecoded(CharSequence name, CharSequence value);
-
-    /**
-     * A more finer-grained version of {@link #onDecoded(CharSequence,
-     * CharSequence)} that also reports on value sensitivity.
-     *
-     * <p> Value sensitivity must be considered, for example, when implementing
-     * an intermediary. A {@code value} is sensitive if it was represented as <a
-     * href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal Header
-     * Field Never Indexed</a>.
-     *
-     * <p> It is required that intermediaries MUST use the {@linkplain
-     * Encoder#header(CharSequence, CharSequence, boolean) same representation}
-     * for encoding this header field in order to protect its value which is not
-     * to be put at risk by compressing it.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes {@code onDecoded(name, value)}.
-     *
-     * @param name
-     *         header name
-     * @param value
-     *         header value
-     * @param sensitive
-     *         whether or not the value is sensitive
-     *
-     * @see #onLiteralNeverIndexed(int, CharSequence, CharSequence, boolean)
-     * @see #onLiteralNeverIndexed(CharSequence, boolean, CharSequence, boolean)
-     */
-    default void onDecoded(CharSequence name, CharSequence value,
-                           boolean sensitive) {
-        onDecoded(name, value);
-    }
-
-    /**
-     * An <a href="https://tools.ietf.org/html/rfc7541#section-6.1">Indexed
-     * Header Field</a> decoded.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, false)}.
-     *
-     * @param index
-     *         index of an entry in the table
-     * @param name
-     *         header name
-     * @param value
-     *         header value
-     */
-    default void onIndexed(int index, CharSequence name, CharSequence value) {
-        onDecoded(name, value, false);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
-     * Header Field without Indexing</a> decoded, where a {@code name} was
-     * referred by an {@code index}.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, false)}.
-     *
-     * @param index
-     *         index of an entry in the table
-     * @param name
-     *         header name
-     * @param value
-     *         header value
-     * @param valueHuffman
-     *         if the {@code value} was Huffman encoded
-     */
-    default void onLiteral(int index, CharSequence name,
-                           CharSequence value, boolean valueHuffman) {
-        onDecoded(name, value, false);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
-     * Header Field without Indexing</a> decoded, where both a {@code name} and
-     * a {@code value} were literal.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, false)}.
-     *
-     * @param name
-     *         header name
-     * @param nameHuffman
-     *         if the {@code name} was Huffman encoded
-     * @param value
-     *         header value
-     * @param valueHuffman
-     *         if the {@code value} was Huffman encoded
-     */
-    default void onLiteral(CharSequence name, boolean nameHuffman,
-                           CharSequence value, boolean valueHuffman) {
-        onDecoded(name, value, false);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
-     * Header Field Never Indexed</a> decoded, where a {@code name}
-     * was referred by an {@code index}.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, true)}.
-     *
-     * @param index
-     *         index of an entry in the table
-     * @param name
-     *         header name
-     * @param value
-     *         header value
-     * @param valueHuffman
-     *         if the {@code value} was Huffman encoded
-     */
-    default void onLiteralNeverIndexed(int index, CharSequence name,
-                                       CharSequence value,
-                                       boolean valueHuffman) {
-        onDecoded(name, value, true);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
-     * Header Field Never Indexed</a> decoded, where both a {@code
-     * name} and a {@code value} were literal.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, true)}.
-     *
-     * @param name
-     *         header name
-     * @param nameHuffman
-     *         if the {@code name} was Huffman encoded
-     * @param value
-     *         header value
-     * @param valueHuffman
-     *         if the {@code value} was Huffman encoded
-     */
-    default void onLiteralNeverIndexed(CharSequence name, boolean nameHuffman,
-                                       CharSequence value, boolean valueHuffman) {
-        onDecoded(name, value, true);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
-     * Header Field with Incremental Indexing</a> decoded, where a {@code name}
-     * was referred by an {@code index}.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, false)}.
-     *
-     * @param index
-     *         index of an entry in the table
-     * @param name
-     *         header name
-     * @param value
-     *         header value
-     * @param valueHuffman
-     *         if the {@code value} was Huffman encoded
-     */
-    default void onLiteralWithIndexing(int index,
-                                       CharSequence name,
-                                       CharSequence value, boolean valueHuffman) {
-        onDecoded(name, value, false);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
-     * Header Field with Incremental Indexing</a> decoded, where both a {@code
-     * name} and a {@code value} were literal.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation invokes
-     * {@code onDecoded(name, value, false)}.
-     *
-     * @param name
-     *         header name
-     * @param nameHuffman
-     *         if the {@code name} was Huffman encoded
-     * @param value
-     *         header value
-     * @param valueHuffman
-     *         if the {@code value} was Huffman encoded
-     */
-    default void onLiteralWithIndexing(CharSequence name, boolean nameHuffman,
-                                       CharSequence value, boolean valueHuffman) {
-        onDecoded(name, value, false);
-    }
-
-    /**
-     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.3">Dynamic Table
-     * Size Update</a> decoded.
-     *
-     * @implSpec
-     *
-     * <p> The default implementation does nothing.
-     *
-     * @param capacity
-     *         new capacity of the header table
-     */
-    default void onSizeUpdate(int capacity) { }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Encoder.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,429 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import java.util.LinkedList;
-import java.util.List;
-
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-
-/**
- * Encodes headers to their binary representation.
- *
- * <p>Typical lifecycle looks like this:
- *
- * <p> {@link #Encoder(int) new Encoder}
- * ({@link #setMaxCapacity(int) setMaxCapacity}?
- * {@link #encode(ByteBuffer) encode})*
- *
- * <p> Suppose headers are represented by {@code Map<String, List<String>>}. A
- * supplier and a consumer of {@link ByteBuffer}s in forms of {@code
- * Supplier<ByteBuffer>} and {@code Consumer<ByteBuffer>} respectively. Then to
- * encode headers, the following approach might be used:
- *
- * <pre>{@code
- *     for (Map.Entry<String, List<String>> h : headers.entrySet()) {
- *         String name = h.getKey();
- *         for (String value : h.getValue()) {
- *             encoder.header(name, value);        // Set up header
- *             boolean encoded;
- *             do {
- *                 ByteBuffer b = buffersSupplier.get();
- *                 encoded = encoder.encode(b);    // Encode the header
- *                 buffersConsumer.accept(b);
- *             } while (!encoded);
- *         }
- *     }
- * }</pre>
- *
- * <p> Though the specification <a
- * href="https://tools.ietf.org/html/rfc7541#section-2"> does not define</a> how
- * an encoder is to be implemented, a default implementation is provided by the
- * method {@link #header(CharSequence, CharSequence, boolean)}.
- *
- * <p> To provide a custom encoding implementation, {@code Encoder} has to be
- * extended. A subclass then can access methods for encoding using specific
- * representations (e.g. {@link #literal(int, CharSequence, boolean) literal},
- * {@link #indexed(int) indexed}, etc.)
- *
- * @apiNote
- *
- * <p> An Encoder provides an incremental way of encoding headers.
- * {@link #encode(ByteBuffer)} takes a buffer a returns a boolean indicating
- * whether, or not, the buffer was sufficiently sized to hold the
- * remaining of the encoded representation.
- *
- * <p> This way, there's no need to provide a buffer of a specific size, or to
- * resize (and copy) the buffer on demand, when the remaining encoded
- * representation will not fit in the buffer's remaining space. Instead, an
- * array of existing buffers can be used, prepended with a frame that encloses
- * the resulting header block afterwards.
- *
- * <p> Splitting the encoding operation into header set up and header encoding,
- * separates long lived arguments ({@code name}, {@code value}, {@code
- * sensitivity}, etc.) from the short lived ones (e.g. {@code buffer}),
- * simplifying each operation itself.
- *
- * @implNote
- *
- * <p> The default implementation does not use dynamic table. It reports to a
- * coupled Decoder a size update with the value of {@code 0}, and never changes
- * it afterwards.
- *
- * @since 9
- */
-public class Encoder {
-
-    // TODO: enum: no huffman/smart huffman/always huffman
-    private static final boolean DEFAULT_HUFFMAN = true;
-
-    private final IndexedWriter indexedWriter = new IndexedWriter();
-    private final LiteralWriter literalWriter = new LiteralWriter();
-    private final LiteralNeverIndexedWriter literalNeverIndexedWriter
-            = new LiteralNeverIndexedWriter();
-    private final LiteralWithIndexingWriter literalWithIndexingWriter
-            = new LiteralWithIndexingWriter();
-    private final SizeUpdateWriter sizeUpdateWriter = new SizeUpdateWriter();
-    private final BulkSizeUpdateWriter bulkSizeUpdateWriter
-            = new BulkSizeUpdateWriter();
-
-    private BinaryRepresentationWriter writer;
-    private final HeaderTable headerTable;
-
-    private boolean encoding;
-
-    private int maxCapacity;
-    private int currCapacity;
-    private int lastCapacity;
-    private long minCapacity;
-    private boolean capacityUpdate;
-    private boolean configuredCapacityUpdate;
-
-    /**
-     * Constructs an {@code Encoder} with the specified maximum capacity of the
-     * header table.
-     *
-     * <p> The value has to be agreed between decoder and encoder out-of-band,
-     * e.g. by a protocol that uses HPACK (see <a
-     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
-     * Size</a>).
-     *
-     * @param maxCapacity
-     *         a non-negative integer
-     *
-     * @throws IllegalArgumentException
-     *         if maxCapacity is negative
-     */
-    public Encoder(int maxCapacity) {
-        if (maxCapacity < 0) {
-            throw new IllegalArgumentException("maxCapacity >= 0: " + maxCapacity);
-        }
-        // Initial maximum capacity update mechanics
-        minCapacity = Long.MAX_VALUE;
-        currCapacity = -1;
-        setMaxCapacity(maxCapacity);
-        headerTable = new HeaderTable(lastCapacity);
-    }
-
-    /**
-     * Sets up the given header {@code (name, value)}.
-     *
-     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
-     *
-     * @param name
-     *         the name
-     * @param value
-     *         the value
-     *
-     * @throws NullPointerException
-     *         if any of the arguments are {@code null}
-     * @throws IllegalStateException
-     *         if the encoder hasn't fully encoded the previous header, or
-     *         hasn't yet started to encode it
-     * @see #header(CharSequence, CharSequence, boolean)
-     */
-    public void header(CharSequence name, CharSequence value)
-            throws IllegalStateException {
-        header(name, value, false);
-    }
-
-    /**
-     * Sets up the given header {@code (name, value)} with possibly sensitive
-     * value.
-     *
-     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
-     *
-     * @param name
-     *         the name
-     * @param value
-     *         the value
-     * @param sensitive
-     *         whether or not the value is sensitive
-     *
-     * @throws NullPointerException
-     *         if any of the arguments are {@code null}
-     * @throws IllegalStateException
-     *         if the encoder hasn't fully encoded the previous header, or
-     *         hasn't yet started to encode it
-     * @see #header(CharSequence, CharSequence)
-     * @see DecodingCallback#onDecoded(CharSequence, CharSequence, boolean)
-     */
-    public void header(CharSequence name, CharSequence value,
-                       boolean sensitive) throws IllegalStateException {
-        // Arguably a good balance between complexity of implementation and
-        // efficiency of encoding
-        requireNonNull(name, "name");
-        requireNonNull(value, "value");
-        HeaderTable t = getHeaderTable();
-        int index = t.indexOf(name, value);
-        if (index > 0) {
-            indexed(index);
-        } else if (index < 0) {
-            if (sensitive) {
-                literalNeverIndexed(-index, value, DEFAULT_HUFFMAN);
-            } else {
-                literal(-index, value, DEFAULT_HUFFMAN);
-            }
-        } else {
-            if (sensitive) {
-                literalNeverIndexed(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
-            } else {
-                literal(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
-            }
-        }
-    }
-
-    /**
-     * Sets a maximum capacity of the header table.
-     *
-     * <p> The value has to be agreed between decoder and encoder out-of-band,
-     * e.g. by a protocol that uses HPACK (see <a
-     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
-     * Size</a>).
-     *
-     * <p> May be called any number of times after or before a complete header
-     * has been encoded.
-     *
-     * <p> If the encoder decides to change the actual capacity, an update will
-     * be encoded before a new encoding operation starts.
-     *
-     * @param capacity
-     *         a non-negative integer
-     *
-     * @throws IllegalArgumentException
-     *         if capacity is negative
-     * @throws IllegalStateException
-     *         if the encoder hasn't fully encoded the previous header, or
-     *         hasn't yet started to encode it
-     */
-    public void setMaxCapacity(int capacity) {
-        checkEncoding();
-        if (capacity < 0) {
-            throw new IllegalArgumentException("capacity >= 0: " + capacity);
-        }
-        int calculated = calculateCapacity(capacity);
-        if (calculated < 0 || calculated > capacity) {
-            throw new IllegalArgumentException(
-                    format("0 <= calculated <= capacity: calculated=%s, capacity=%s",
-                            calculated, capacity));
-        }
-        capacityUpdate = true;
-        // maxCapacity needs to be updated unconditionally, so the encoder
-        // always has the newest one (in case it decides to update it later
-        // unsolicitedly)
-        // Suppose maxCapacity = 4096, and the encoder has decided to use only
-        // 2048. It later can choose anything else from the region [0, 4096].
-        maxCapacity = capacity;
-        lastCapacity = calculated;
-        minCapacity = Math.min(minCapacity, lastCapacity);
-    }
-
-    protected int calculateCapacity(int maxCapacity) {
-        // Default implementation of the Encoder won't add anything to the
-        // table, therefore no need for a table space
-        return 0;
-    }
-
-    /**
-     * Encodes the {@linkplain #header(CharSequence, CharSequence) set up}
-     * header into the given buffer.
-     *
-     * <p> The encoder writes as much as possible of the header's binary
-     * representation into the given buffer, starting at the buffer's position,
-     * and increments its position to reflect the bytes written. The buffer's
-     * mark and limit will not be modified.
-     *
-     * <p> Once the method has returned {@code true}, the current header is
-     * deemed encoded. A new header may be set up.
-     *
-     * @param headerBlock
-     *         the buffer to encode the header into, may be empty
-     *
-     * @return {@code true} if the current header has been fully encoded,
-     *         {@code false} otherwise
-     *
-     * @throws NullPointerException
-     *         if the buffer is {@code null}
-     * @throws ReadOnlyBufferException
-     *         if this buffer is read-only
-     * @throws IllegalStateException
-     *         if there is no set up header
-     */
-    public final boolean encode(ByteBuffer headerBlock) {
-        if (!encoding) {
-            throw new IllegalStateException("A header hasn't been set up");
-        }
-        if (!prependWithCapacityUpdate(headerBlock)) {
-            return false;
-        }
-        boolean done = writer.write(headerTable, headerBlock);
-        if (done) {
-            writer.reset(); // FIXME: WHY?
-            encoding = false;
-        }
-        return done;
-    }
-
-    private boolean prependWithCapacityUpdate(ByteBuffer headerBlock) {
-        if (capacityUpdate) {
-            if (!configuredCapacityUpdate) {
-                List<Integer> sizes = new LinkedList<>();
-                if (minCapacity < currCapacity) {
-                    sizes.add((int) minCapacity);
-                    if (minCapacity != lastCapacity) {
-                        sizes.add(lastCapacity);
-                    }
-                } else if (lastCapacity != currCapacity) {
-                    sizes.add(lastCapacity);
-                }
-                bulkSizeUpdateWriter.maxHeaderTableSizes(sizes);
-                configuredCapacityUpdate = true;
-            }
-            boolean done = bulkSizeUpdateWriter.write(headerTable, headerBlock);
-            if (done) {
-                minCapacity = lastCapacity;
-                currCapacity = lastCapacity;
-                bulkSizeUpdateWriter.reset();
-                capacityUpdate = false;
-                configuredCapacityUpdate = false;
-            }
-            return done;
-        }
-        return true;
-    }
-
-    protected final void indexed(int index) throws IndexOutOfBoundsException {
-        checkEncoding();
-        encoding = true;
-        writer = indexedWriter.index(index);
-    }
-
-    protected final void literal(int index, CharSequence value,
-                                 boolean useHuffman)
-            throws IndexOutOfBoundsException {
-        checkEncoding();
-        encoding = true;
-        writer = literalWriter
-                .index(index).value(value, useHuffman);
-    }
-
-    protected final void literal(CharSequence name, boolean nameHuffman,
-                                 CharSequence value, boolean valueHuffman) {
-        checkEncoding();
-        encoding = true;
-        writer = literalWriter
-                .name(name, nameHuffman).value(value, valueHuffman);
-    }
-
-    protected final void literalNeverIndexed(int index,
-                                             CharSequence value,
-                                             boolean valueHuffman)
-            throws IndexOutOfBoundsException {
-        checkEncoding();
-        encoding = true;
-        writer = literalNeverIndexedWriter
-                .index(index).value(value, valueHuffman);
-    }
-
-    protected final void literalNeverIndexed(CharSequence name,
-                                             boolean nameHuffman,
-                                             CharSequence value,
-                                             boolean valueHuffman) {
-        checkEncoding();
-        encoding = true;
-        writer = literalNeverIndexedWriter
-                .name(name, nameHuffman).value(value, valueHuffman);
-    }
-
-    protected final void literalWithIndexing(int index,
-                                             CharSequence value,
-                                             boolean valueHuffman)
-            throws IndexOutOfBoundsException {
-        checkEncoding();
-        encoding = true;
-        writer = literalWithIndexingWriter
-                .index(index).value(value, valueHuffman);
-    }
-
-    protected final void literalWithIndexing(CharSequence name,
-                                             boolean nameHuffman,
-                                             CharSequence value,
-                                             boolean valueHuffman) {
-        checkEncoding();
-        encoding = true;
-        writer = literalWithIndexingWriter
-                .name(name, nameHuffman).value(value, valueHuffman);
-    }
-
-    protected final void sizeUpdate(int capacity)
-            throws IllegalArgumentException {
-        checkEncoding();
-        // Ensure subclass follows the contract
-        if (capacity > this.maxCapacity) {
-            throw new IllegalArgumentException(
-                    format("capacity <= maxCapacity: capacity=%s, maxCapacity=%s",
-                            capacity, maxCapacity));
-        }
-        writer = sizeUpdateWriter.maxHeaderTableSize(capacity);
-    }
-
-    protected final int getMaxCapacity() {
-        return maxCapacity;
-    }
-
-    protected final HeaderTable getHeaderTable() {
-        return headerTable;
-    }
-
-    protected final void checkEncoding() {
-        if (encoding) {
-            throw new IllegalStateException(
-                    "Previous encoding operation hasn't finished yet");
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/HeaderTable.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import static java.lang.String.format;
-
-//
-// Header Table combined from two tables: static and dynamic.
-//
-// There is a single address space for index values. Index-aware methods
-// correspond to the table as a whole. Size-aware methods only to the dynamic
-// part of it.
-//
-final class HeaderTable {
-
-    private static final HeaderField[] staticTable = {
-            null, // To make index 1-based, instead of 0-based
-            new HeaderField(":authority"),
-            new HeaderField(":method", "GET"),
-            new HeaderField(":method", "POST"),
-            new HeaderField(":path", "/"),
-            new HeaderField(":path", "/index.html"),
-            new HeaderField(":scheme", "http"),
-            new HeaderField(":scheme", "https"),
-            new HeaderField(":status", "200"),
-            new HeaderField(":status", "204"),
-            new HeaderField(":status", "206"),
-            new HeaderField(":status", "304"),
-            new HeaderField(":status", "400"),
-            new HeaderField(":status", "404"),
-            new HeaderField(":status", "500"),
-            new HeaderField("accept-charset"),
-            new HeaderField("accept-encoding", "gzip, deflate"),
-            new HeaderField("accept-language"),
-            new HeaderField("accept-ranges"),
-            new HeaderField("accept"),
-            new HeaderField("access-control-allow-origin"),
-            new HeaderField("age"),
-            new HeaderField("allow"),
-            new HeaderField("authorization"),
-            new HeaderField("cache-control"),
-            new HeaderField("content-disposition"),
-            new HeaderField("content-encoding"),
-            new HeaderField("content-language"),
-            new HeaderField("content-length"),
-            new HeaderField("content-location"),
-            new HeaderField("content-range"),
-            new HeaderField("content-type"),
-            new HeaderField("cookie"),
-            new HeaderField("date"),
-            new HeaderField("etag"),
-            new HeaderField("expect"),
-            new HeaderField("expires"),
-            new HeaderField("from"),
-            new HeaderField("host"),
-            new HeaderField("if-match"),
-            new HeaderField("if-modified-since"),
-            new HeaderField("if-none-match"),
-            new HeaderField("if-range"),
-            new HeaderField("if-unmodified-since"),
-            new HeaderField("last-modified"),
-            new HeaderField("link"),
-            new HeaderField("location"),
-            new HeaderField("max-forwards"),
-            new HeaderField("proxy-authenticate"),
-            new HeaderField("proxy-authorization"),
-            new HeaderField("range"),
-            new HeaderField("referer"),
-            new HeaderField("refresh"),
-            new HeaderField("retry-after"),
-            new HeaderField("server"),
-            new HeaderField("set-cookie"),
-            new HeaderField("strict-transport-security"),
-            new HeaderField("transfer-encoding"),
-            new HeaderField("user-agent"),
-            new HeaderField("vary"),
-            new HeaderField("via"),
-            new HeaderField("www-authenticate")
-    };
-
-    private static final int STATIC_TABLE_LENGTH = staticTable.length - 1;
-    private static final int ENTRY_SIZE = 32;
-    private static final Map<String, LinkedHashMap<String, Integer>> staticIndexes;
-
-    static {
-        staticIndexes = new HashMap<>(STATIC_TABLE_LENGTH);
-        for (int i = 1; i <= STATIC_TABLE_LENGTH; i++) {
-            HeaderField f = staticTable[i];
-            Map<String, Integer> values = staticIndexes
-                    .computeIfAbsent(f.name, k -> new LinkedHashMap<>());
-            values.put(f.value, i);
-        }
-    }
-
-    private final Table dynamicTable = new Table(0);
-    private int maxSize;
-    private int size;
-
-    public HeaderTable(int maxSize) {
-        setMaxSize(maxSize);
-    }
-
-    //
-    // The method returns:
-    //
-    // * a positive integer i where i (i = [1..Integer.MAX_VALUE]) is an
-    // index of an entry with a header (n, v), where n.equals(name) &&
-    // v.equals(value)
-    //
-    // * a negative integer j where j (j = [-Integer.MAX_VALUE..-1]) is an
-    // index of an entry with a header (n, v), where n.equals(name)
-    //
-    // * 0 if there's no entry e such that e.getName().equals(name)
-    //
-    // The rationale behind this design is to allow to pack more useful data
-    // into a single invocation, facilitating a single pass where possible
-    // (the idea is the same as in java.util.Arrays.binarySearch(int[], int)).
-    //
-    public int indexOf(CharSequence name, CharSequence value) {
-        // Invoking toString() will possibly allocate Strings for the sake of
-        // the search, which doesn't feel right.
-        String n = name.toString();
-        String v = value.toString();
-
-        // 1. Try exact match in the static region
-        Map<String, Integer> values = staticIndexes.get(n);
-        if (values != null) {
-            Integer idx = values.get(v);
-            if (idx != null) {
-                return idx;
-            }
-        }
-        // 2. Try exact match in the dynamic region
-        int didx = dynamicTable.indexOf(n, v);
-        if (didx > 0) {
-            return STATIC_TABLE_LENGTH + didx;
-        } else if (didx < 0) {
-            if (values != null) {
-                // 3. Return name match from the static region
-                return -values.values().iterator().next(); // Iterator allocation
-            } else {
-                // 4. Return name match from the dynamic region
-                return -STATIC_TABLE_LENGTH + didx;
-            }
-        } else {
-            if (values != null) {
-                // 3. Return name match from the static region
-                return -values.values().iterator().next(); // Iterator allocation
-            } else {
-                return 0;
-            }
-        }
-    }
-
-    public int size() {
-        return size;
-    }
-
-    public int maxSize() {
-        return maxSize;
-    }
-
-    public int length() {
-        return STATIC_TABLE_LENGTH + dynamicTable.size();
-    }
-
-    HeaderField get(int index) {
-        checkIndex(index);
-        if (index <= STATIC_TABLE_LENGTH) {
-            return staticTable[index];
-        } else {
-            return dynamicTable.get(index - STATIC_TABLE_LENGTH);
-        }
-    }
-
-    void put(CharSequence name, CharSequence value) {
-        // Invoking toString() will possibly allocate Strings. But that's
-        // unavoidable at this stage. If a CharSequence is going to be stored in
-        // the table, it must not be mutable (e.g. for the sake of hashing).
-        put(new HeaderField(name.toString(), value.toString()));
-    }
-
-    private void put(HeaderField h) {
-        int entrySize = sizeOf(h);
-        while (entrySize > maxSize - size && size != 0) {
-            evictEntry();
-        }
-        if (entrySize > maxSize - size) {
-            return;
-        }
-        size += entrySize;
-        dynamicTable.add(h);
-    }
-
-    void setMaxSize(int maxSize) {
-        if (maxSize < 0) {
-            throw new IllegalArgumentException
-                    ("maxSize >= 0: maxSize=" + maxSize);
-        }
-        while (maxSize < size && size != 0) {
-            evictEntry();
-        }
-        this.maxSize = maxSize;
-        int upperBound = (maxSize / ENTRY_SIZE) + 1;
-        this.dynamicTable.setCapacity(upperBound);
-    }
-
-    HeaderField evictEntry() {
-        HeaderField f = dynamicTable.remove();
-        size -= sizeOf(f);
-        return f;
-    }
-
-    @Override
-    public String toString() {
-        double used = maxSize == 0 ? 0 : 100 * (((double) size) / maxSize);
-        return format("entries: %d; used %s/%s (%.1f%%)", dynamicTable.size(),
-                size, maxSize, used);
-    }
-
-    int checkIndex(int index) {
-        if (index < 1 || index > STATIC_TABLE_LENGTH + dynamicTable.size()) {
-            throw new IllegalArgumentException(
-                    format("1 <= index <= length(): index=%s, length()=%s",
-                            index, length()));
-        }
-        return index;
-    }
-
-    int sizeOf(HeaderField f) {
-        return f.name.length() + f.value.length() + ENTRY_SIZE;
-    }
-
-    //
-    // Diagnostic information in the form used in the RFC 7541
-    //
-    String getStateString() {
-        if (size == 0) {
-            return "empty.";
-        }
-
-        StringBuilder b = new StringBuilder();
-        for (int i = 1, size = dynamicTable.size(); i <= size; i++) {
-            HeaderField e = dynamicTable.get(i);
-            b.append(format("[%3d] (s = %3d) %s: %s\n", i,
-                    sizeOf(e), e.name, e.value));
-        }
-        b.append(format("      Table size:%4s", this.size));
-        return b.toString();
-    }
-
-    // Convert to a Value Object (JDK-8046159)?
-    static final class HeaderField {
-
-        final String name;
-        final String value;
-
-        public HeaderField(String name) {
-            this(name, "");
-        }
-
-        public HeaderField(String name, String value) {
-            this.name = name;
-            this.value = value;
-        }
-
-        @Override
-        public String toString() {
-            return value.isEmpty() ? name : name + ": " + value;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-            HeaderField that = (HeaderField) o;
-            return name.equals(that.name) && value.equals(that.value);
-        }
-
-        @Override
-        public int hashCode() {
-            return 31 * name.hashCode() + value.hashCode();
-        }
-    }
-
-    //
-    // To quickly find an index of an entry in the dynamic table with the given
-    // contents an effective inverse mapping is needed. Here's a simple idea
-    // behind such a mapping.
-    //
-    // # The problem:
-    //
-    // We have a queue with an O(1) lookup by index:
-    //
-    //     get: index -> x
-    //
-    // What we want is an O(1) reverse lookup:
-    //
-    //     indexOf: x -> index
-    //
-    // # Solution:
-    //
-    // Let's store an inverse mapping in a Map<x, Integer>. This have a problem
-    // that when a new element is added to the queue, all indexes in the map
-    // become invalid. Namely, the new element is assigned with an index of 1,
-    // and each index i, i > 1 becomes shifted by 1 to the left:
-    //
-    //     1, 1, 2, 3, ... , n-1, n
-    //
-    // Re-establishing the invariant would seem to require a pass through the
-    // map incrementing all indexes (map values) by 1, which is O(n).
-    //
-    // The good news is we can do much better then this!
-    //
-    // Let's create a single field of type long, called 'counter'. Then each
-    // time a new element 'x' is added to the queue, a value of this field gets
-    // incremented. Then the resulting value of the 'counter_x' is then put as a
-    // value under key 'x' to the map:
-    //
-    //    map.put(x, counter_x)
-    //
-    // It gives us a map that maps an element to a value the counter had at the
-    // time the element had been added.
-    //
-    // In order to retrieve an index of any element 'x' in the queue (at any
-    // given time) we simply need to subtract the value (the snapshot of the
-    // counter at the time when the 'x' was added) from the current value of the
-    // counter. This operation basically answers the question:
-    //
-    //     How many elements ago 'x' was the tail of the queue?
-    //
-    // Which is the same as its index in the queue now. Given, of course, it's
-    // still in the queue.
-    //
-    // I'm pretty sure in a real life long overflow will never happen, so it's
-    // not too practical to add recalibrating code, but a pedantic person might
-    // want to do so:
-    //
-    //     if (counter == Long.MAX_VALUE) {
-    //         recalibrate();
-    //     }
-    //
-    // Where 'recalibrate()' goes through the table doing this:
-    //
-    //     value -= counter
-    //
-    // That's given, of course, the size of the table itself is less than
-    // Long.MAX_VALUE :-)
-    //
-    private static final class Table {
-
-        private final Map<String, Map<String, Long>> map;
-        private final CircularBuffer<HeaderField> buffer;
-        private long counter = 1;
-
-        Table(int capacity) {
-            buffer = new CircularBuffer<>(capacity);
-            map = new HashMap<>(capacity);
-        }
-
-        void add(HeaderField f) {
-            buffer.add(f);
-            Map<String, Long> values = map.computeIfAbsent(f.name, k -> new HashMap<>());
-            values.put(f.value, counter++);
-        }
-
-        HeaderField get(int index) {
-            return buffer.get(index - 1);
-        }
-
-        int indexOf(String name, String value) {
-            Map<String, Long> values = map.get(name);
-            if (values == null) {
-                return 0;
-            }
-            Long index = values.get(value);
-            if (index != null) {
-                return (int) (counter - index);
-            } else {
-                assert !values.isEmpty();
-                Long any = values.values().iterator().next(); // Iterator allocation
-                return -(int) (counter - any);
-            }
-        }
-
-        HeaderField remove() {
-            HeaderField f = buffer.remove();
-            Map<String, Long> values = map.get(f.name);
-            Long index = values.remove(f.value);
-            assert index != null;
-            if (values.isEmpty()) {
-                map.remove(f.name);
-            }
-            return f;
-        }
-
-        int size() {
-            return buffer.size;
-        }
-
-        public void setCapacity(int capacity) {
-            buffer.resize(capacity);
-        }
-    }
-
-    //                    head
-    //                    v
-    // [ ][ ][A][B][C][D][ ][ ][ ]
-    //        ^
-    //        tail
-    //
-    //       |<- size ->| (4)
-    // |<------ capacity ------->| (9)
-    //
-    static final class CircularBuffer<E> {
-
-        int tail, head, size, capacity;
-        Object[] elements;
-
-        CircularBuffer(int capacity) {
-            this.capacity = capacity;
-            elements = new Object[capacity];
-        }
-
-        void add(E elem) {
-            if (size == capacity) {
-                throw new IllegalStateException(
-                        format("No room for '%s': capacity=%s", elem, capacity));
-            }
-            elements[head] = elem;
-            head = (head + 1) % capacity;
-            size++;
-        }
-
-        @SuppressWarnings("unchecked")
-        E remove() {
-            if (size == 0) {
-                throw new NoSuchElementException("Empty");
-            }
-            E elem = (E) elements[tail];
-            elements[tail] = null;
-            tail = (tail + 1) % capacity;
-            size--;
-            return elem;
-        }
-
-        @SuppressWarnings("unchecked")
-        E get(int index) {
-            if (index < 0 || index >= size) {
-                throw new IndexOutOfBoundsException(
-                        format("0 <= index <= capacity: index=%s, capacity=%s",
-                                index, capacity));
-            }
-            int idx = (tail + (size - index - 1)) % capacity;
-            return (E) elements[idx];
-        }
-
-        public void resize(int newCapacity) {
-            if (newCapacity < size) {
-                throw new IllegalStateException(
-                        format("newCapacity >= size: newCapacity=%s, size=%s",
-                                newCapacity, size));
-            }
-
-            Object[] newElements = new Object[newCapacity];
-
-            if (tail < head || size == 0) {
-                System.arraycopy(elements, tail, newElements, 0, size);
-            } else {
-                System.arraycopy(elements, tail, newElements, 0, elements.length - tail);
-                System.arraycopy(elements, 0, newElements, elements.length - tail, head);
-            }
-
-            elements = newElements;
-            tail = 0;
-            head = size;
-            this.capacity = newCapacity;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Huffman.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,676 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.ByteBuffer;
-
-import static java.lang.String.format;
-
-/**
- * Huffman coding table.
- *
- * <p> Instances of this class are safe for use by multiple threads.
- *
- * @since 9
- */
-public final class Huffman {
-
-    // TODO: check if reset is done in both reader and writer
-
-    static final class Reader {
-
-        private Node curr; // position in the trie
-        private int len;   // length of the path from the root to 'curr'
-        private int p;     // byte probe
-
-        {
-            reset();
-        }
-
-        public void read(ByteBuffer source, Appendable destination,
-                         boolean isLast) {
-            read(source, destination, true, isLast);
-        }
-
-        // Takes 'isLast' rather than returns whether the reading is done or
-        // not, for more informative exceptions.
-        void read(ByteBuffer source, Appendable destination, boolean reportEOS,
-                  boolean isLast) {
-
-            Node c = curr;
-            int l = len;
-            /*
-               Since ByteBuffer is itself stateful, its position is
-               remembered here NOT as a part of Reader's state,
-               but to set it back in the case of a failure
-             */
-            int pos = source.position();
-
-            while (source.hasRemaining()) {
-                int d = source.get();
-                for (; p != 0; p >>= 1) {
-                    c = c.getChild(p & d);
-                    l++;
-                    if (c.isLeaf()) {
-                        if (reportEOS && c.isEOSPath) {
-                            throw new IllegalArgumentException("Encountered EOS");
-                        }
-                        try {
-                            destination.append(c.getChar());
-                        } catch (RuntimeException | Error e) {
-                            source.position(pos);
-                            throw e;
-                        } catch (IOException e) {
-                            source.position(pos);
-                            throw new UncheckedIOException(e);
-                        }
-                        c = INSTANCE.root;
-                        l = 0;
-                    }
-                    curr = c;
-                    len = l;
-                }
-                resetProbe();
-                pos++;
-            }
-            if (!isLast) {
-                return; // it's too early to jump to any conclusions, let's wait
-            }
-            if (c.isLeaf()) {
-                return; // it's perfectly ok, no extra padding bits
-            }
-            if (c.isEOSPath && len <= 7) {
-                return; // it's ok, some extra padding bits
-            }
-            if (c.isEOSPath) {
-                throw new IllegalArgumentException(
-                        "Padding is too long (len=" + len + ") " +
-                                "or unexpected end of data");
-            }
-            throw new IllegalArgumentException(
-                    "Not a EOS prefix padding or unexpected end of data");
-        }
-
-        public void reset() {
-            curr = INSTANCE.root;
-            len = 0;
-            resetProbe();
-        }
-
-        private void resetProbe() {
-            p = 0x80;
-        }
-    }
-
-    static final class Writer {
-
-        private int pos;       // position in 'source'
-        private int avail = 8; // number of least significant bits available in 'curr'
-        private int curr;      // next byte to put to the destination
-        private int rem;       // number of least significant bits in 'code' yet to be processed
-        private int code;      // current code being written
-
-        private CharSequence source;
-        private int end;
-
-        public Writer from(CharSequence input, int start, int end) {
-            if (start < 0 || end < 0 || end > input.length() || start > end) {
-                throw new IndexOutOfBoundsException(
-                        String.format("input.length()=%s, start=%s, end=%s",
-                                input.length(), start, end));
-            }
-            pos = start;
-            this.end = end;
-            this.source = input;
-            return this;
-        }
-
-        public boolean write(ByteBuffer destination) {
-            for (; pos < end; pos++) {
-                if (rem == 0) {
-                    Code desc = INSTANCE.codeOf(source.charAt(pos));
-                    rem = desc.length;
-                    code = desc.code;
-                }
-                while (rem > 0) {
-                    if (rem < avail) {
-                        curr |= (code << (avail - rem));
-                        avail -= rem;
-                        rem = 0;
-                    } else {
-                        int c = (curr | (code >>> (rem - avail)));
-                        if (destination.hasRemaining()) {
-                            destination.put((byte) c);
-                        } else {
-                            return false;
-                        }
-                        curr = c;
-                        code <<= (32 - rem + avail);  // throw written bits off the cliff (is this Sparta?)
-                        code >>>= (32 - rem + avail); // return to the position
-                        rem -= avail;
-                        curr = 0;
-                        avail = 8;
-                    }
-                }
-            }
-
-            if (avail < 8) { // have to pad
-                if (destination.hasRemaining()) {
-                    destination.put((byte) (curr | (INSTANCE.EOS.code >>> (INSTANCE.EOS.length - avail))));
-                    avail = 8;
-                } else {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        public Writer reset() {
-            source = null;
-            end = -1;
-            pos = -1;
-            avail = 8;
-            curr = 0;
-            code = 0;
-            return this;
-        }
-    }
-
-    /**
-     * Shared instance.
-     */
-    public static final Huffman INSTANCE = new Huffman();
-
-    private final Code EOS = new Code(0x3fffffff, 30);
-    private final Code[] codes = new Code[257];
-    private final Node root = new Node() {
-        @Override
-        public String toString() { return "root"; }
-    };
-
-    // TODO: consider builder and immutable trie
-    private Huffman() {
-        // @formatter:off
-        addChar(0,   0x1ff8,     13);
-        addChar(1,   0x7fffd8,   23);
-        addChar(2,   0xfffffe2,  28);
-        addChar(3,   0xfffffe3,  28);
-        addChar(4,   0xfffffe4,  28);
-        addChar(5,   0xfffffe5,  28);
-        addChar(6,   0xfffffe6,  28);
-        addChar(7,   0xfffffe7,  28);
-        addChar(8,   0xfffffe8,  28);
-        addChar(9,   0xffffea,   24);
-        addChar(10,  0x3ffffffc, 30);
-        addChar(11,  0xfffffe9,  28);
-        addChar(12,  0xfffffea,  28);
-        addChar(13,  0x3ffffffd, 30);
-        addChar(14,  0xfffffeb,  28);
-        addChar(15,  0xfffffec,  28);
-        addChar(16,  0xfffffed,  28);
-        addChar(17,  0xfffffee,  28);
-        addChar(18,  0xfffffef,  28);
-        addChar(19,  0xffffff0,  28);
-        addChar(20,  0xffffff1,  28);
-        addChar(21,  0xffffff2,  28);
-        addChar(22,  0x3ffffffe, 30);
-        addChar(23,  0xffffff3,  28);
-        addChar(24,  0xffffff4,  28);
-        addChar(25,  0xffffff5,  28);
-        addChar(26,  0xffffff6,  28);
-        addChar(27,  0xffffff7,  28);
-        addChar(28,  0xffffff8,  28);
-        addChar(29,  0xffffff9,  28);
-        addChar(30,  0xffffffa,  28);
-        addChar(31,  0xffffffb,  28);
-        addChar(32,  0x14,        6);
-        addChar(33,  0x3f8,      10);
-        addChar(34,  0x3f9,      10);
-        addChar(35,  0xffa,      12);
-        addChar(36,  0x1ff9,     13);
-        addChar(37,  0x15,        6);
-        addChar(38,  0xf8,        8);
-        addChar(39,  0x7fa,      11);
-        addChar(40,  0x3fa,      10);
-        addChar(41,  0x3fb,      10);
-        addChar(42,  0xf9,        8);
-        addChar(43,  0x7fb,      11);
-        addChar(44,  0xfa,        8);
-        addChar(45,  0x16,        6);
-        addChar(46,  0x17,        6);
-        addChar(47,  0x18,        6);
-        addChar(48,  0x0,         5);
-        addChar(49,  0x1,         5);
-        addChar(50,  0x2,         5);
-        addChar(51,  0x19,        6);
-        addChar(52,  0x1a,        6);
-        addChar(53,  0x1b,        6);
-        addChar(54,  0x1c,        6);
-        addChar(55,  0x1d,        6);
-        addChar(56,  0x1e,        6);
-        addChar(57,  0x1f,        6);
-        addChar(58,  0x5c,        7);
-        addChar(59,  0xfb,        8);
-        addChar(60,  0x7ffc,     15);
-        addChar(61,  0x20,        6);
-        addChar(62,  0xffb,      12);
-        addChar(63,  0x3fc,      10);
-        addChar(64,  0x1ffa,     13);
-        addChar(65,  0x21,        6);
-        addChar(66,  0x5d,        7);
-        addChar(67,  0x5e,        7);
-        addChar(68,  0x5f,        7);
-        addChar(69,  0x60,        7);
-        addChar(70,  0x61,        7);
-        addChar(71,  0x62,        7);
-        addChar(72,  0x63,        7);
-        addChar(73,  0x64,        7);
-        addChar(74,  0x65,        7);
-        addChar(75,  0x66,        7);
-        addChar(76,  0x67,        7);
-        addChar(77,  0x68,        7);
-        addChar(78,  0x69,        7);
-        addChar(79,  0x6a,        7);
-        addChar(80,  0x6b,        7);
-        addChar(81,  0x6c,        7);
-        addChar(82,  0x6d,        7);
-        addChar(83,  0x6e,        7);
-        addChar(84,  0x6f,        7);
-        addChar(85,  0x70,        7);
-        addChar(86,  0x71,        7);
-        addChar(87,  0x72,        7);
-        addChar(88,  0xfc,        8);
-        addChar(89,  0x73,        7);
-        addChar(90,  0xfd,        8);
-        addChar(91,  0x1ffb,     13);
-        addChar(92,  0x7fff0,    19);
-        addChar(93,  0x1ffc,     13);
-        addChar(94,  0x3ffc,     14);
-        addChar(95,  0x22,        6);
-        addChar(96,  0x7ffd,     15);
-        addChar(97,  0x3,         5);
-        addChar(98,  0x23,        6);
-        addChar(99,  0x4,         5);
-        addChar(100, 0x24,        6);
-        addChar(101, 0x5,         5);
-        addChar(102, 0x25,        6);
-        addChar(103, 0x26,        6);
-        addChar(104, 0x27,        6);
-        addChar(105, 0x6,         5);
-        addChar(106, 0x74,        7);
-        addChar(107, 0x75,        7);
-        addChar(108, 0x28,        6);
-        addChar(109, 0x29,        6);
-        addChar(110, 0x2a,        6);
-        addChar(111, 0x7,         5);
-        addChar(112, 0x2b,        6);
-        addChar(113, 0x76,        7);
-        addChar(114, 0x2c,        6);
-        addChar(115, 0x8,         5);
-        addChar(116, 0x9,         5);
-        addChar(117, 0x2d,        6);
-        addChar(118, 0x77,        7);
-        addChar(119, 0x78,        7);
-        addChar(120, 0x79,        7);
-        addChar(121, 0x7a,        7);
-        addChar(122, 0x7b,        7);
-        addChar(123, 0x7ffe,     15);
-        addChar(124, 0x7fc,      11);
-        addChar(125, 0x3ffd,     14);
-        addChar(126, 0x1ffd,     13);
-        addChar(127, 0xffffffc,  28);
-        addChar(128, 0xfffe6,    20);
-        addChar(129, 0x3fffd2,   22);
-        addChar(130, 0xfffe7,    20);
-        addChar(131, 0xfffe8,    20);
-        addChar(132, 0x3fffd3,   22);
-        addChar(133, 0x3fffd4,   22);
-        addChar(134, 0x3fffd5,   22);
-        addChar(135, 0x7fffd9,   23);
-        addChar(136, 0x3fffd6,   22);
-        addChar(137, 0x7fffda,   23);
-        addChar(138, 0x7fffdb,   23);
-        addChar(139, 0x7fffdc,   23);
-        addChar(140, 0x7fffdd,   23);
-        addChar(141, 0x7fffde,   23);
-        addChar(142, 0xffffeb,   24);
-        addChar(143, 0x7fffdf,   23);
-        addChar(144, 0xffffec,   24);
-        addChar(145, 0xffffed,   24);
-        addChar(146, 0x3fffd7,   22);
-        addChar(147, 0x7fffe0,   23);
-        addChar(148, 0xffffee,   24);
-        addChar(149, 0x7fffe1,   23);
-        addChar(150, 0x7fffe2,   23);
-        addChar(151, 0x7fffe3,   23);
-        addChar(152, 0x7fffe4,   23);
-        addChar(153, 0x1fffdc,   21);
-        addChar(154, 0x3fffd8,   22);
-        addChar(155, 0x7fffe5,   23);
-        addChar(156, 0x3fffd9,   22);
-        addChar(157, 0x7fffe6,   23);
-        addChar(158, 0x7fffe7,   23);
-        addChar(159, 0xffffef,   24);
-        addChar(160, 0x3fffda,   22);
-        addChar(161, 0x1fffdd,   21);
-        addChar(162, 0xfffe9,    20);
-        addChar(163, 0x3fffdb,   22);
-        addChar(164, 0x3fffdc,   22);
-        addChar(165, 0x7fffe8,   23);
-        addChar(166, 0x7fffe9,   23);
-        addChar(167, 0x1fffde,   21);
-        addChar(168, 0x7fffea,   23);
-        addChar(169, 0x3fffdd,   22);
-        addChar(170, 0x3fffde,   22);
-        addChar(171, 0xfffff0,   24);
-        addChar(172, 0x1fffdf,   21);
-        addChar(173, 0x3fffdf,   22);
-        addChar(174, 0x7fffeb,   23);
-        addChar(175, 0x7fffec,   23);
-        addChar(176, 0x1fffe0,   21);
-        addChar(177, 0x1fffe1,   21);
-        addChar(178, 0x3fffe0,   22);
-        addChar(179, 0x1fffe2,   21);
-        addChar(180, 0x7fffed,   23);
-        addChar(181, 0x3fffe1,   22);
-        addChar(182, 0x7fffee,   23);
-        addChar(183, 0x7fffef,   23);
-        addChar(184, 0xfffea,    20);
-        addChar(185, 0x3fffe2,   22);
-        addChar(186, 0x3fffe3,   22);
-        addChar(187, 0x3fffe4,   22);
-        addChar(188, 0x7ffff0,   23);
-        addChar(189, 0x3fffe5,   22);
-        addChar(190, 0x3fffe6,   22);
-        addChar(191, 0x7ffff1,   23);
-        addChar(192, 0x3ffffe0,  26);
-        addChar(193, 0x3ffffe1,  26);
-        addChar(194, 0xfffeb,    20);
-        addChar(195, 0x7fff1,    19);
-        addChar(196, 0x3fffe7,   22);
-        addChar(197, 0x7ffff2,   23);
-        addChar(198, 0x3fffe8,   22);
-        addChar(199, 0x1ffffec,  25);
-        addChar(200, 0x3ffffe2,  26);
-        addChar(201, 0x3ffffe3,  26);
-        addChar(202, 0x3ffffe4,  26);
-        addChar(203, 0x7ffffde,  27);
-        addChar(204, 0x7ffffdf,  27);
-        addChar(205, 0x3ffffe5,  26);
-        addChar(206, 0xfffff1,   24);
-        addChar(207, 0x1ffffed,  25);
-        addChar(208, 0x7fff2,    19);
-        addChar(209, 0x1fffe3,   21);
-        addChar(210, 0x3ffffe6,  26);
-        addChar(211, 0x7ffffe0,  27);
-        addChar(212, 0x7ffffe1,  27);
-        addChar(213, 0x3ffffe7,  26);
-        addChar(214, 0x7ffffe2,  27);
-        addChar(215, 0xfffff2,   24);
-        addChar(216, 0x1fffe4,   21);
-        addChar(217, 0x1fffe5,   21);
-        addChar(218, 0x3ffffe8,  26);
-        addChar(219, 0x3ffffe9,  26);
-        addChar(220, 0xffffffd,  28);
-        addChar(221, 0x7ffffe3,  27);
-        addChar(222, 0x7ffffe4,  27);
-        addChar(223, 0x7ffffe5,  27);
-        addChar(224, 0xfffec,    20);
-        addChar(225, 0xfffff3,   24);
-        addChar(226, 0xfffed,    20);
-        addChar(227, 0x1fffe6,   21);
-        addChar(228, 0x3fffe9,   22);
-        addChar(229, 0x1fffe7,   21);
-        addChar(230, 0x1fffe8,   21);
-        addChar(231, 0x7ffff3,   23);
-        addChar(232, 0x3fffea,   22);
-        addChar(233, 0x3fffeb,   22);
-        addChar(234, 0x1ffffee,  25);
-        addChar(235, 0x1ffffef,  25);
-        addChar(236, 0xfffff4,   24);
-        addChar(237, 0xfffff5,   24);
-        addChar(238, 0x3ffffea,  26);
-        addChar(239, 0x7ffff4,   23);
-        addChar(240, 0x3ffffeb,  26);
-        addChar(241, 0x7ffffe6,  27);
-        addChar(242, 0x3ffffec,  26);
-        addChar(243, 0x3ffffed,  26);
-        addChar(244, 0x7ffffe7,  27);
-        addChar(245, 0x7ffffe8,  27);
-        addChar(246, 0x7ffffe9,  27);
-        addChar(247, 0x7ffffea,  27);
-        addChar(248, 0x7ffffeb,  27);
-        addChar(249, 0xffffffe,  28);
-        addChar(250, 0x7ffffec,  27);
-        addChar(251, 0x7ffffed,  27);
-        addChar(252, 0x7ffffee,  27);
-        addChar(253, 0x7ffffef,  27);
-        addChar(254, 0x7fffff0,  27);
-        addChar(255, 0x3ffffee,  26);
-        addEOS (256, EOS.code,   EOS.length);
-        // @formatter:on
-    }
-
-
-    /**
-     * Calculates the number of bytes required to represent the given {@code
-     * CharSequence} with the Huffman coding.
-     *
-     * @param value
-     *         characters
-     *
-     * @return number of bytes
-     *
-     * @throws NullPointerException
-     *         if the value is null
-     */
-    public int lengthOf(CharSequence value) {
-        return lengthOf(value, 0, value.length());
-    }
-
-    /**
-     * Calculates the number of bytes required to represent a subsequence of the
-     * given {@code CharSequence} with the Huffman coding.
-     *
-     * @param value
-     *         characters
-     * @param start
-     *         the start index, inclusive
-     * @param end
-     *         the end index, exclusive
-     *
-     * @return number of bytes
-     *
-     * @throws NullPointerException
-     *         if the value is null
-     * @throws IndexOutOfBoundsException
-     *         if any invocation of {@code value.charAt(i)}, where {@code start
-     *         <= i < end} would throw an IndexOutOfBoundsException
-     */
-    public int lengthOf(CharSequence value, int start, int end) {
-        int len = 0;
-        for (int i = start; i < end; i++) {
-            char c = value.charAt(i);
-            len += INSTANCE.codeOf(c).length;
-        }
-        // Integer division with ceiling, assumption:
-        assert (len / 8 + (len % 8 != 0 ? 1 : 0)) == (len + 7) / 8 : len;
-        return (len + 7) / 8;
-    }
-
-    private void addChar(int c, int code, int bitLength) {
-        addLeaf(c, code, bitLength, false);
-        codes[c] = new Code(code, bitLength);
-    }
-
-    private void addEOS(int c, int code, int bitLength) {
-        addLeaf(c, code, bitLength, true);
-        codes[c] = new Code(code, bitLength);
-    }
-
-    private void addLeaf(int c, int code, int bitLength, boolean isEOS) {
-        if (bitLength < 1) {
-            throw new IllegalArgumentException("bitLength < 1");
-        }
-        Node curr = root;
-        for (int p = 1 << bitLength - 1; p != 0 && !curr.isLeaf(); p = p >> 1) {
-            curr.isEOSPath |= isEOS; // If it's already true, it can't become false
-            curr = curr.addChildIfAbsent(p & code);
-        }
-        curr.isEOSPath |= isEOS; // The last one needs to have this property as well
-        if (curr.isLeaf()) {
-            throw new IllegalStateException("Specified code is already taken");
-        }
-        curr.setChar((char) c);
-    }
-
-    private Code codeOf(char c) {
-        if (c > 255) {
-            throw new IllegalArgumentException("char=" + ((int) c));
-        }
-        return codes[c];
-    }
-
-    //
-    // For debugging/testing purposes
-    //
-    Node getRoot() {
-        return root;
-    }
-
-    //
-    // Guarantees:
-    //
-    //  if (isLeaf() == true) => getChar() is a legal call
-    //  if (isLeaf() == false) => getChild(i) is a legal call (though it can
-    //                                                           return null)
-    //
-    static class Node {
-
-        Node left;
-        Node right;
-        boolean isEOSPath;
-
-        boolean charIsSet;
-        char c;
-
-        Node getChild(int selector) {
-            if (isLeaf()) {
-                throw new IllegalStateException("This is a leaf node");
-            }
-            Node result = selector == 0 ? left : right;
-            if (result == null) {
-                throw new IllegalStateException(format(
-                        "Node doesn't have a child (selector=%s)", selector));
-            }
-            return result;
-        }
-
-        boolean isLeaf() {
-            return charIsSet;
-        }
-
-        char getChar() {
-            if (!isLeaf()) {
-                throw new IllegalStateException("This node is not a leaf node");
-            }
-            return c;
-        }
-
-        void setChar(char c) {
-            if (charIsSet) {
-                throw new IllegalStateException(
-                        "This node has been taken already");
-            }
-            if (left != null || right != null) {
-                throw new IllegalStateException("The node cannot be made "
-                        + "a leaf as it's already has a child");
-            }
-            this.c = c;
-            charIsSet = true;
-        }
-
-        Node addChildIfAbsent(int i) {
-            if (charIsSet) {
-                throw new IllegalStateException("The node cannot have a child "
-                        + "as it's already a leaf node");
-            }
-            Node child;
-            if (i == 0) {
-                if ((child = left) == null) {
-                    child = left = new Node();
-                }
-            } else {
-                if ((child = right) == null) {
-                    child = right = new Node();
-                }
-            }
-            return child;
-        }
-
-        @Override
-        public String toString() {
-            if (isLeaf()) {
-                if (isEOSPath) {
-                    return "EOS";
-                } else {
-                    return format("char: (%3s) '%s'", (int) c, c);
-                }
-            }
-            return "/\\";
-        }
-    }
-
-    // TODO: value-based class?
-    // FIXME: can we re-use Node instead of this class?
-    private static final class Code {
-
-        final int code;
-        final int length;
-
-        private Code(int code, int length) {
-            this.code = code;
-            this.length = length;
-        }
-
-        public int getCode() {
-            return code;
-        }
-
-        public int getLength() {
-            return length;
-        }
-
-        @Override
-        public String toString() {
-            long p = 1 << length;
-            return Long.toBinaryString(code + p).substring(1)
-                    + ", length=" + length;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/ISO_8859_1.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.ByteBuffer;
-
-//
-// Custom implementation of ISO/IEC 8859-1:1998
-//
-// The rationale behind this is not to deal with CharsetEncoder/CharsetDecoder,
-// basically because it would require wrapping every single CharSequence into a
-// CharBuffer and then copying it back.
-//
-// But why not to give a CharBuffer instead of Appendable? Because I can choose
-// an Appendable (e.g. StringBuilder) that adjusts its length when needed and
-// therefore not to deal with pre-sized CharBuffers or copying.
-//
-// The encoding is simple and well known: 1 byte <-> 1 char
-//
-final class ISO_8859_1 {
-
-    private ISO_8859_1() { }
-
-    public static final class Reader {
-
-        public void read(ByteBuffer source, Appendable destination) {
-            for (int i = 0, len = source.remaining(); i < len; i++) {
-                char c = (char) (source.get() & 0xff);
-                try {
-                    destination.append(c);
-                } catch (IOException e) {
-                    throw new UncheckedIOException
-                            ("Error appending to the destination", e);
-                }
-            }
-        }
-
-        public Reader reset() {
-            return this;
-        }
-    }
-
-    public static final class Writer {
-
-        private CharSequence source;
-        private int pos;
-        private int end;
-
-        public Writer configure(CharSequence source, int start, int end) {
-            this.source = source;
-            this.pos = start;
-            this.end = end;
-            return this;
-        }
-
-        public boolean write(ByteBuffer destination) {
-            for (; pos < end; pos++) {
-                char c = source.charAt(pos);
-                if (c > '\u00FF') {
-                    throw new IllegalArgumentException(
-                            "Illegal ISO-8859-1 char: " + (int) c);
-                }
-                if (destination.hasRemaining()) {
-                    destination.put((byte) c);
-                } else {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        public Writer reset() {
-            source = null;
-            pos = -1;
-            end = -1;
-            return this;
-        }
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexNameValueWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-
-abstract class IndexNameValueWriter implements BinaryRepresentationWriter {
-
-    private final int pattern;
-    private final int prefix;
-    private final IntegerWriter intWriter = new IntegerWriter();
-    private final StringWriter nameWriter = new StringWriter();
-    private final StringWriter valueWriter = new StringWriter();
-
-    protected boolean indexedRepresentation;
-
-    private static final int NEW               = 0;
-    private static final int NAME_PART_WRITTEN = 1;
-    private static final int VALUE_WRITTEN     = 2;
-
-    private int state = NEW;
-
-    protected IndexNameValueWriter(int pattern, int prefix) {
-        this.pattern = pattern;
-        this.prefix = prefix;
-    }
-
-    IndexNameValueWriter index(int index) {
-        indexedRepresentation = true;
-        intWriter.configure(index, prefix, pattern);
-        return this;
-    }
-
-    IndexNameValueWriter name(CharSequence name, boolean useHuffman) {
-        indexedRepresentation = false;
-        intWriter.configure(0, prefix, pattern);
-        nameWriter.configure(name, useHuffman);
-        return this;
-    }
-
-    IndexNameValueWriter value(CharSequence value, boolean useHuffman) {
-        valueWriter.configure(value, useHuffman);
-        return this;
-    }
-
-    @Override
-    public boolean write(HeaderTable table, ByteBuffer destination) {
-        if (state < NAME_PART_WRITTEN) {
-            if (indexedRepresentation) {
-                if (!intWriter.write(destination)) {
-                    return false;
-                }
-            } else {
-                if (!intWriter.write(destination) || !nameWriter.write(destination)) {
-                    return false;
-                }
-            }
-            state = NAME_PART_WRITTEN;
-        }
-        if (state < VALUE_WRITTEN) {
-            if (!valueWriter.write(destination)) {
-                return false;
-            }
-            state = VALUE_WRITTEN;
-        }
-        return state == VALUE_WRITTEN;
-    }
-
-    @Override
-    public IndexNameValueWriter reset() {
-        intWriter.reset();
-        if (!indexedRepresentation) {
-            nameWriter.reset();
-        }
-        valueWriter.reset();
-        state = NEW;
-        return this;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexedWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-
-final class IndexedWriter implements BinaryRepresentationWriter {
-
-    private final IntegerWriter intWriter = new IntegerWriter();
-
-    IndexedWriter() { }
-
-    IndexedWriter index(int index) {
-        intWriter.configure(index, 7, 0b1000_0000);
-        return this;
-    }
-
-    @Override
-    public boolean write(HeaderTable table, ByteBuffer destination) {
-        return intWriter.write(destination);
-    }
-
-    @Override
-    public BinaryRepresentationWriter reset() {
-        intWriter.reset();
-        return this;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerReader.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-import static java.lang.String.format;
-
-final class IntegerReader {
-
-    private static final int NEW             = 0;
-    private static final int CONFIGURED      = 1;
-    private static final int FIRST_BYTE_READ = 2;
-    private static final int DONE            = 4;
-
-    private int state = NEW;
-
-    private int N;
-    private int maxValue;
-    private int value;
-    private long r;
-    private long b = 1;
-
-    public IntegerReader configure(int N) {
-        return configure(N, Integer.MAX_VALUE);
-    }
-
-    //
-    // Why is it important to configure 'maxValue' here. After all we can wait
-    // for the integer to be fully read and then check it. Can't we?
-    //
-    // Two reasons.
-    //
-    // 1. Value wraps around long won't be unnoticed.
-    // 2. It can spit out an exception as soon as it becomes clear there's
-    // an overflow. Therefore, no need to wait for the value to be fully read.
-    //
-    public IntegerReader configure(int N, int maxValue) {
-        if (state != NEW) {
-            throw new IllegalStateException("Already configured");
-        }
-        checkPrefix(N);
-        if (maxValue < 0) {
-            throw new IllegalArgumentException(
-                    "maxValue >= 0: maxValue=" + maxValue);
-        }
-        this.maxValue = maxValue;
-        this.N = N;
-        state = CONFIGURED;
-        return this;
-    }
-
-    public boolean read(ByteBuffer input) {
-        if (state == NEW) {
-            throw new IllegalStateException("Configure first");
-        }
-        if (state == DONE) {
-            return true;
-        }
-        if (!input.hasRemaining()) {
-            return false;
-        }
-        if (state == CONFIGURED) {
-            int max = (2 << (N - 1)) - 1;
-            int n = input.get() & max;
-            if (n != max) {
-                value = n;
-                state = DONE;
-                return true;
-            } else {
-                r = max;
-            }
-            state = FIRST_BYTE_READ;
-        }
-        if (state == FIRST_BYTE_READ) {
-            // variable-length quantity (VLQ)
-            byte i;
-            do {
-                if (!input.hasRemaining()) {
-                    return false;
-                }
-                i = input.get();
-                long increment = b * (i & 127);
-                if (r + increment > maxValue) {
-                    throw new IllegalArgumentException(format(
-                            "Integer overflow: maxValue=%,d, value=%,d",
-                            maxValue, r + increment));
-                }
-                r += increment;
-                b *= 128;
-            } while ((128 & i) == 128);
-
-            value = (int) r;
-            state = DONE;
-            return true;
-        }
-        throw new InternalError(Arrays.toString(
-                new Object[]{state, N, maxValue, value, r, b}));
-    }
-
-    public int get() throws IllegalStateException {
-        if (state != DONE) {
-            throw new IllegalStateException("Has not been fully read yet");
-        }
-        return value;
-    }
-
-    private static void checkPrefix(int N) {
-        if (N < 1 || N > 8) {
-            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
-        }
-    }
-
-    public IntegerReader reset() {
-        b = 1;
-        state = NEW;
-        return this;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-final class IntegerWriter {
-
-    private static final int NEW                = 0;
-    private static final int CONFIGURED         = 1;
-    private static final int FIRST_BYTE_WRITTEN = 2;
-    private static final int DONE               = 4;
-
-    private int state = NEW;
-
-    private int payload;
-    private int N;
-    private int value;
-
-    //
-    //      0   1   2   3   4   5   6   7
-    //    +---+---+---+---+---+---+---+---+
-    //    |   |   |   |   |   |   |   |   |
-    //    +---+---+---+-------------------+
-    //    |<--------->|<----------------->|
-    //       payload           N=5
-    //
-    // payload is the contents of the left-hand side part of the octet;
-    //         it is truncated to fit into 8-N bits, where 1 <= N <= 8;
-    //
-    public IntegerWriter configure(int value, int N, int payload) {
-        if (state != NEW) {
-            throw new IllegalStateException("Already configured");
-        }
-        if (value < 0) {
-            throw new IllegalArgumentException("value >= 0: value=" + value);
-        }
-        checkPrefix(N);
-        this.value = value;
-        this.N = N;
-        this.payload = payload & 0xFF & (0xFFFFFFFF << N);
-        state = CONFIGURED;
-        return this;
-    }
-
-    public boolean write(ByteBuffer output) {
-        if (state == NEW) {
-            throw new IllegalStateException("Configure first");
-        }
-        if (state == DONE) {
-            return true;
-        }
-
-        if (!output.hasRemaining()) {
-            return false;
-        }
-        if (state == CONFIGURED) {
-            int max = (2 << (N - 1)) - 1;
-            if (value < max) {
-                output.put((byte) (payload | value));
-                state = DONE;
-                return true;
-            }
-            output.put((byte) (payload | max));
-            value -= max;
-            state = FIRST_BYTE_WRITTEN;
-        }
-        if (state == FIRST_BYTE_WRITTEN) {
-            while (value >= 128 && output.hasRemaining()) {
-                output.put((byte) (value % 128 + 128));
-                value /= 128;
-            }
-            if (!output.hasRemaining()) {
-                return false;
-            }
-            output.put((byte) value);
-            state = DONE;
-            return true;
-        }
-        throw new InternalError(Arrays.toString(
-                new Object[]{state, payload, N, value}));
-    }
-
-    private static void checkPrefix(int N) {
-        if (N < 1 || N > 8) {
-            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
-        }
-    }
-
-    public IntegerWriter reset() {
-        state = NEW;
-        return this;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralNeverIndexedWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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 sun.net.httpclient.hpack;
-
-final class LiteralNeverIndexedWriter extends IndexNameValueWriter {
-
-    LiteralNeverIndexedWriter() {
-        super(0b0001_0000, 4);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWithIndexingWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +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 sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-
-final class LiteralWithIndexingWriter extends IndexNameValueWriter {
-
-    private boolean tableUpdated;
-
-    private CharSequence name;
-    private CharSequence value;
-    private int index;
-
-    LiteralWithIndexingWriter() {
-        super(0b0100_0000, 6);
-    }
-
-    @Override
-    LiteralWithIndexingWriter index(int index) {
-        super.index(index);
-        this.index = index;
-        return this;
-    }
-
-    @Override
-    LiteralWithIndexingWriter name(CharSequence name, boolean useHuffman) {
-        super.name(name, useHuffman);
-        this.name = name;
-        return this;
-    }
-
-    @Override
-    LiteralWithIndexingWriter value(CharSequence value, boolean useHuffman) {
-        super.value(value, useHuffman);
-        this.value = value;
-        return this;
-    }
-
-    @Override
-    public boolean write(HeaderTable table, ByteBuffer destination) {
-        if (!tableUpdated) {
-            CharSequence n;
-            if (indexedRepresentation) {
-                n = table.get(index).name;
-            } else {
-                n = name;
-            }
-            table.put(n, value);
-            tableUpdated = true;
-        }
-        return super.write(table, destination);
-    }
-
-    @Override
-    public IndexNameValueWriter reset() {
-        tableUpdated = false;
-        name = null;
-        value = null;
-        index = -1;
-        return super.reset();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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 sun.net.httpclient.hpack;
-
-final class LiteralWriter extends IndexNameValueWriter {
-
-    LiteralWriter() {
-        super(0b0000_0000, 4);
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/SizeUpdateWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-
-final class SizeUpdateWriter implements BinaryRepresentationWriter {
-
-    private final IntegerWriter intWriter = new IntegerWriter();
-    private int maxSize;
-    private boolean tableUpdated;
-
-    SizeUpdateWriter() { }
-
-    SizeUpdateWriter maxHeaderTableSize(int size) {
-        intWriter.configure(size, 5, 0b0010_0000);
-        this.maxSize = size;
-        return this;
-    }
-
-    @Override
-    public boolean write(HeaderTable table, ByteBuffer destination) {
-        if (!tableUpdated) {
-            table.setMaxSize(maxSize);
-            tableUpdated = true;
-        }
-        return intWriter.write(destination);
-    }
-
-    @Override
-    public BinaryRepresentationWriter reset() {
-        intWriter.reset();
-        maxSize = -1;
-        tableUpdated = false;
-        return this;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringReader.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-//
-//          0   1   2   3   4   5   6   7
-//        +---+---+---+---+---+---+---+---+
-//        | H |    String Length (7+)     |
-//        +---+---------------------------+
-//        |  String Data (Length octets)  |
-//        +-------------------------------+
-//
-final class StringReader {
-
-    private static final int NEW             = 0;
-    private static final int FIRST_BYTE_READ = 1;
-    private static final int LENGTH_READ     = 2;
-    private static final int DONE            = 4;
-
-    private final IntegerReader intReader = new IntegerReader();
-    private final Huffman.Reader huffmanReader = new Huffman.Reader();
-    private final ISO_8859_1.Reader plainReader = new ISO_8859_1.Reader();
-
-    private int state = NEW;
-
-    private boolean huffman;
-    private int remainingLength;
-
-    boolean read(ByteBuffer input, Appendable output) {
-        if (state == DONE) {
-            return true;
-        }
-        if (!input.hasRemaining()) {
-            return false;
-        }
-        if (state == NEW) {
-            int p = input.position();
-            huffman = (input.get(p) & 0b10000000) != 0;
-            state = FIRST_BYTE_READ;
-            intReader.configure(7);
-        }
-        if (state == FIRST_BYTE_READ) {
-            boolean lengthRead = intReader.read(input);
-            if (!lengthRead) {
-                return false;
-            }
-            remainingLength = intReader.get();
-            state = LENGTH_READ;
-        }
-        if (state == LENGTH_READ) {
-            boolean isLast = input.remaining() >= remainingLength;
-            int oldLimit = input.limit();
-            if (isLast) {
-                input.limit(input.position() + remainingLength);
-            }
-            remainingLength -= Math.min(input.remaining(), remainingLength);
-            if (huffman) {
-                huffmanReader.read(input, output, isLast);
-            } else {
-                plainReader.read(input, output);
-            }
-            if (isLast) {
-                input.limit(oldLimit);
-                state = DONE;
-            }
-            return isLast;
-        }
-        throw new InternalError(Arrays.toString(
-                new Object[]{state, huffman, remainingLength}));
-    }
-
-    boolean isHuffmanEncoded() {
-        if (state < FIRST_BYTE_READ) {
-            throw new IllegalStateException("Has not been fully read yet");
-        }
-        return huffman;
-    }
-
-    void reset() {
-        if (huffman) {
-            huffmanReader.reset();
-        } else {
-            plainReader.reset();
-        }
-        intReader.reset();
-        state = NEW;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-//
-//          0   1   2   3   4   5   6   7
-//        +---+---+---+---+---+---+---+---+
-//        | H |    String Length (7+)     |
-//        +---+---------------------------+
-//        |  String Data (Length octets)  |
-//        +-------------------------------+
-//
-// StringWriter does not require a notion of endOfInput (isLast) in 'write'
-// methods due to the nature of string representation in HPACK. Namely, the
-// length of the string is put before string's contents. Therefore the length is
-// always known beforehand.
-//
-// Expected use:
-//
-//     configure write* (reset configure write*)*
-//
-final class StringWriter {
-
-    private static final int NEW            = 0;
-    private static final int CONFIGURED     = 1;
-    private static final int LENGTH_WRITTEN = 2;
-    private static final int DONE           = 4;
-
-    private final IntegerWriter intWriter = new IntegerWriter();
-    private final Huffman.Writer huffmanWriter = new Huffman.Writer();
-    private final ISO_8859_1.Writer plainWriter = new ISO_8859_1.Writer();
-
-    private int state = NEW;
-    private boolean huffman;
-
-    StringWriter configure(CharSequence input, boolean huffman) {
-        return configure(input, 0, input.length(), huffman);
-    }
-
-    StringWriter configure(CharSequence input, int start, int end,
-                           boolean huffman) {
-        if (start < 0 || end < 0 || end > input.length() || start > end) {
-            throw new IndexOutOfBoundsException(
-                    String.format("input.length()=%s, start=%s, end=%s",
-                            input.length(), start, end));
-        }
-        if (!huffman) {
-            plainWriter.configure(input, start, end);
-            intWriter.configure(end - start, 7, 0b0000_0000);
-        } else {
-            huffmanWriter.from(input, start, end);
-            intWriter.configure(Huffman.INSTANCE.lengthOf(input, start, end),
-                    7, 0b1000_0000);
-        }
-
-        this.huffman = huffman;
-        state = CONFIGURED;
-        return this;
-    }
-
-    boolean write(ByteBuffer output) {
-        if (state == DONE) {
-            return true;
-        }
-        if (state == NEW) {
-            throw new IllegalStateException("Configure first");
-        }
-        if (!output.hasRemaining()) {
-            return false;
-        }
-        if (state == CONFIGURED) {
-            if (intWriter.write(output)) {
-                state = LENGTH_WRITTEN;
-            } else {
-                return false;
-            }
-        }
-        if (state == LENGTH_WRITTEN) {
-            boolean written = huffman
-                    ? huffmanWriter.write(output)
-                    : plainWriter.write(output);
-            if (written) {
-                state = DONE;
-                return true;
-            } else {
-                return false;
-            }
-        }
-        throw new InternalError(Arrays.toString(new Object[]{state, huffman}));
-    }
-
-    void reset() {
-        intWriter.reset();
-        if (huffman) {
-            huffmanWriter.reset();
-        } else {
-            plainWriter.reset();
-        }
-        state = NEW;
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/package-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/**
- * HPACK (Header Compression for HTTP/2) implementation conforming to
- * <a href="https://tools.ietf.org/html/rfc7541">RFC&nbsp;7541</a>.
- *
- * <p> Headers can be decoded and encoded by {@link sun.net.httpclient.hpack.Decoder}
- * and {@link sun.net.httpclient.hpack.Encoder} respectively.
- *
- * <p> Instances of these classes are not safe for use by multiple threads.
- */
-package sun.net.httpclient.hpack;
--- a/jdk/src/java.logging/share/classes/java/util/logging/Level.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.logging/share/classes/java/util/logging/Level.java	Tue Dec 13 02:04:23 2016 +0100
@@ -79,8 +79,13 @@
     private static final String defaultBundle =
         "sun.util.logging.resources.logging";
 
-    private static final JavaUtilResourceBundleAccess RB_ACCESS =
-        SharedSecrets.getJavaUtilResourceBundleAccess();
+    // Calling SharedSecrets.getJavaUtilResourceBundleAccess()
+    // forces the initialization of ResourceBundle.class, which
+    // can be too early if the VM has not finished booting yet.
+    private static final class RbAccess {
+        static final JavaUtilResourceBundleAccess RB_ACCESS =
+            SharedSecrets.getJavaUtilResourceBundleAccess();
+    }
 
     /**
      * @serial  The non-localized name of the level.
@@ -286,7 +291,7 @@
         // or its defining class loader, if it's unnamed module,
         // of this Level instance that can be a custom Level subclass;
         Module module = this.getClass().getModule();
-        ResourceBundle rb = RB_ACCESS.getBundle(resourceBundleName,
+        ResourceBundle rb = RbAccess.RB_ACCESS.getBundle(resourceBundleName,
                 newLocale, module);
 
         final String localizedName = rb.getString(name);
--- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java	Tue Dec 13 02:04:23 2016 +0100
@@ -259,8 +259,13 @@
     private static final LoggerBundle NO_RESOURCE_BUNDLE =
             new LoggerBundle(null, null);
 
-    private static final JavaUtilResourceBundleAccess RB_ACCESS =
+    // Calling SharedSecrets.getJavaUtilResourceBundleAccess()
+    // forces the initialization of ResourceBundle.class, which
+    // can be too early if the VM has not finished booting yet.
+    private static final class RbAccess {
+        static final JavaUtilResourceBundleAccess RB_ACCESS =
             SharedSecrets.getJavaUtilResourceBundleAccess();
+    }
 
     // A value class that holds the logger configuration data.
     // This configuration can be shared between an application logger
@@ -2183,7 +2188,7 @@
         if (!useCallersModule || callerModule == null || !callerModule.isNamed()) {
             try {
                 Module mod = cl.getUnnamedModule();
-                catalog = RB_ACCESS.getBundle(name, currentLocale, mod);
+                catalog = RbAccess.RB_ACCESS.getBundle(name, currentLocale, mod);
                 catalogName = name;
                 catalogLocale = currentLocale;
                 return catalog;
@@ -2227,7 +2232,7 @@
             // Try with the caller's module
             try {
                 // Use the caller's module
-                catalog = RB_ACCESS.getBundle(name, currentLocale, callerModule);
+                catalog = RbAccess.RB_ACCESS.getBundle(name, currentLocale, callerModule);
                 catalogName = name;
                 catalogLocale = currentLocale;
                 return catalog;
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/resources/rmid.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/resources/rmid.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -87,13 +87,10 @@
 # class/permission names.
 rmid.exec.perms.inadequate=\
 	Activation.main: warning: sun.rmi.activation.execPolicy system\n\
-        property unspecified and no ExecPermissions/ExecOptionPermissions\n\
-        granted; subsequent activation attempts may fail due to unsuccessful\n\
-	ExecPermission/ExecOptionPermission permission checks.  For\n\
-	documentation on how to configure rmid security, refer to:\n\
-\n\
-        http://java.sun.com/j2se/1.4/docs/tooldocs/solaris/rmid.html\n\
-        http://java.sun.com/j2se/1.4/docs/tooldocs/win32/rmid.html\n
+    property unspecified and no ExecPermissions/ExecOptionPermissions\n\
+    granted; subsequent activation attempts may fail due to unsuccessful\n\
+    ExecPermission/ExecOptionPermission permission checks. \n\
+    To configure security, refer to the rmid documentation.\n
 
 # "rmid", "-port", "-log", "-stop", "-C" and "-J" should not be translated,
 # because they are syntax
--- a/jdk/src/java.se/share/classes/module-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/java.se/share/classes/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -34,5 +34,4 @@
     requires transitive java.compact3;
     requires transitive java.datatransfer;
     requires transitive java.desktop;
-    requires transitive java.httpclient;
 }
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c	Tue Dec 13 02:04:23 2016 +0100
@@ -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.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@
  *   Dr Vipul Gupta <vipul.gupta@sun.com> and
  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
  *
- * Last Modified Date from the Original Code: April 2015
+ * Last Modified Date from the Original Code: Nov 2016
  *********************************************************************** */
 
 #include "mplogic.h"
@@ -258,6 +258,7 @@
 #if EC_DEBUG
     printf("ec_NewKey called\n");
 #endif
+    k.dp = (mp_digit*)NULL;
 
     if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@
  *   Dr Vipul Gupta <vipul.gupta@sun.com> and
  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
  *
- * Last Modified Date from the Original Code: March 2012
+ * Last Modified Date from the Original Code: Nov 2016
  *********************************************************************** */
 
 #include <sys/types.h>
@@ -119,6 +119,9 @@
     params->name = name;
     curveParams = ecCurve_map[params->name];
     CHECK_OK(curveParams);
+    if ((strlen(curveParams->genx) + strlen(curveParams->geny)) > 2 * 2 * MAX_ECKEY_LEN) {
+        goto cleanup;
+    }
     params->fieldID.size = curveParams->size;
     params->fieldID.type = field_type;
     if (field_type == ec_field_GFp) {
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ecl_mult.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ecl_mult.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -33,6 +33,7 @@
  * Contributor(s):
  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
  *
+ * Last Modified Date from the Original Code: Nov 2016
  *********************************************************************** */
 
 #include "mpi.h"
@@ -72,6 +73,7 @@
                 if (group->base_point_mul) {
                         MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
                 } else {
+                        kt.flag = (mp_sign)0;
                         MP_CHECKOK(group->
                                            point_mul(&kt, &group->genx, &group->geny, rx, ry,
                                                                  group));
@@ -82,6 +84,7 @@
                         MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
                         MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
                 } else {
+                        kt.flag = (mp_sign)0;
                         MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
                 }
         }
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@
  *   Netscape Communications Corporation
  *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
  *
- * Last Modified Date from the Original Code: June 2014
+ * Last Modified Date from the Original Code: Nov 2016
  *********************************************************************** */
 
 /*  Arbitrary precision integer arithmetic library */
@@ -659,6 +659,7 @@
       goto CLEANUP;
   }
 
+  s.flag = (mp_sign)0;
   s_mp_exch(&s, c);
 
 CLEANUP:
@@ -1609,6 +1610,7 @@
       goto CLEANUP;
   }
 
+  s.flag = (mp_sign)0;
   s_mp_exch(&s, c);
 
 CLEANUP:
@@ -4183,6 +4185,7 @@
 {
   mp_err   res;
   mp_int   tmp;
+  tmp.flag = (mp_sign)0;
 
   if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)
     return res;
@@ -4220,6 +4223,8 @@
   mp_digit div_msd;
   int      ix;
 
+  t.dp = (mp_digit *)NULL;
+
   if(mp_cmp_z(div) == 0)
     return MP_RANGE;
 
--- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -95,6 +95,8 @@
         throwOutOfMemoryError(env, 0);
         return NULL_PTR;
     }
+    ckpInitArgs->flags = (CK_FLAGS)0;
+    ckpInitArgs->pReserved = (CK_VOID_PTR)NULL;
 
     /* Set the mutex functions that will call the Java mutex functions, but
      * only set it, if the field is not null.
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c	Tue Dec 13 02:04:23 2016 +0100
@@ -122,14 +122,14 @@
   jResult = NULL;
   if (ftab->ucryptoVersion != NULL && ftab->ucryptoGetMechList != NULL) {
       length = (*ftab->ucryptoGetMechList)(NULL);
-      if (DEBUG) printf("mech list length: %d\n", length);
+      if (J2UC_DEBUG) printf("mech list length: %d\n", length);
       result = malloc(length);
       if (result == NULL) {
         throwOutOfMemoryError(env, NULL);
         return NULL;
       }
       length = (*ftab->ucryptoGetMechList)(result);
-      if (DEBUG) printf("mech list: %s\n", result);
+      if (J2UC_DEBUG) printf("mech list: %s\n", result);
       jResult = (*env)->NewStringUTF(env, result);
       free(result);
   } else {
@@ -201,7 +201,7 @@
   void *iv;
   size_t ivLen;
 
-  if (DEBUG) printf("CipherInit: mech %i, key %i(%i), iv %i(%i) tagLen %i, aad %i(%i)\n",
+  if (J2UC_DEBUG) printf("CipherInit: mech %i, key %i(%i), iv %i(%i) tagLen %i, aad %i(%i)\n",
                     mech, jKey, jKeyLen, jIv, jIvLen, tagLen, jAad, jAadLen);
   if (mech == CRYPTO_AES_CTR) {
     ivLen = sizeof(CK_AES_CTR_PARAMS);
@@ -228,10 +228,10 @@
   }
   if (encrypt) {
     rv = (*ftab->ucryptoEncryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen);
-    if (rv != 0 && DEBUG) printError("ucryptoEncryptInit", mech, rv);
+    if (rv != 0 && J2UC_DEBUG) printError("ucryptoEncryptInit", mech, rv);
   } else {
     rv =(*ftab->ucryptoDecryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen);
-    if (rv != 0 && DEBUG) printError("ucryptoDecryptInit", mech, rv);
+    if (rv != 0 && J2UC_DEBUG) printError("ucryptoDecryptInit", mech, rv);
   }
 
   if (iv != jIv) {
@@ -253,23 +253,23 @@
   size_t outLength;
 
   outLength = (size_t) *outLen;
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
     printf("CipherUpdate: Inofs %i, InLen %i, OutOfs %i, OutLen %i\n", inOfs, inLen, outOfs, *outLen);
     printBytes("BufIn=", (unsigned char*)(bufIn+inOfs), inLen);
   }
   if (encrypt) {
     rv = (*ftab->ucryptoEncryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength);
     if (rv) {
-      if (DEBUG) printError("ucryptoEncryptUpdate", -1, rv);
+      if (J2UC_DEBUG) printError("ucryptoEncryptUpdate", -1, rv);
     } else {
       *outLen = (int)outLength;
     }
   } else {
     rv = (*ftab->ucryptoDecryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength);
     if (rv) {
-      if (DEBUG) printError("ucryptoDecryptUpdate", -1, rv);
+      if (J2UC_DEBUG) printError("ucryptoDecryptUpdate", -1, rv);
     } else {
-      if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
+      if (J2UC_DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
       *outLen = (int)outLength;
     }
   }
@@ -285,21 +285,21 @@
 
   outLength = (size_t)*outLen;
 
-  if (DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen);
+  if (J2UC_DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen);
   if (encrypt) {
     rv = (*ftab->ucryptoEncryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength);
     if (rv) {
-      if (DEBUG) printError("ucryptoDecryptFinal", -1, rv);
+      if (J2UC_DEBUG) printError("ucryptoDecryptFinal", -1, rv);
     } else {
-      if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
+      if (J2UC_DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
       *outLen = (int)outLength;
     }
   } else {
     rv = (*ftab->ucryptoDecryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength);
     if (rv) {
-      if (DEBUG) printError("ucryptoDecryptFinal", -1, rv);
+      if (J2UC_DEBUG) printError("ucryptoDecryptFinal", -1, rv);
     } else {
-      if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
+      if (J2UC_DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
       *outLen = (int)outLength;
     }
   }
@@ -318,7 +318,7 @@
     rv = (*ftab->ucryptoDigestInit)(context, (ucrypto_mech_t) mech, NULL, 0);
     if (rv) {
       freeContext(context);
-      if (DEBUG) printError("ucryptoDigestInit", mech, rv);
+      if (J2UC_DEBUG) printError("ucryptoDigestInit", mech, rv);
       return 0L;
     }
   }
@@ -336,7 +336,7 @@
 
   if (rv) {
     freeContext(context);
-    if (DEBUG) printError("ucryptoDigestUpdate", mech, rv);
+    if (J2UC_DEBUG) printError("ucryptoDigestUpdate", mech, rv);
   }
 
   return -rv; // use negative value to indicate error
@@ -353,7 +353,7 @@
                                    &digest_len);
   if (rv) {
     freeContext(context);
-    if (DEBUG) printError("ucryptoDigestFinal", mech, rv);
+    if (J2UC_DEBUG) printError("ucryptoDigestFinal", mech, rv);
   }
 
   return -rv; // use negative value to indicate error
@@ -959,7 +959,7 @@
     memcpy(pub, jPub, pubLen);
   }
 
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
     printf("RSAPublicKey.nativeInit: keyValue=%ld, keyLen=2\n", pKey);
     printBytes("\tmod: ", (unsigned char*) mod, modLen);
     printBytes("\tpubExp: ", (unsigned char*) pub, pubLen);
@@ -1035,7 +1035,7 @@
     rv = (*ftab->ucryptoVerifyInit)(context, mech, pKey, keyLength,
                                     NULL, 0);
   }
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
     printf("SignatureInit: context=%ld, mech=%d, sign=%d, keyValue=%ld, keyLength=%d\n",
            context, mech, sign, pKey, keyLength);
     printError("SignatureInit", mech, rv);
@@ -1100,7 +1100,7 @@
   int rv = 0;
 
   context = (crypto_ctx_t *) pCtxt;
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
     printf("NativeRSASignature.nativeUpdate: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n",
            context, sign, jIn, jInOfs, jInLen);
   }
@@ -1111,7 +1111,7 @@
   }
   if (rv) {
     freeContext(context);
-    if (DEBUG) printError("NativeRSASignature.nativeUpdate", -1, rv);
+    if (J2UC_DEBUG) printError("NativeRSASignature.nativeUpdate", -1, rv);
     return -rv; // use negative value to indicate error!
   }
 
@@ -1128,7 +1128,7 @@
     return -1; // use negative value to indicate error!
   }
 
-  if (DEBUG) printBytes("Update w/ data: ", (unsigned char*)bufIn, (size_t) inLen);
+  if (J2UC_DEBUG) printBytes("Update w/ data: ", (unsigned char*)bufIn, (size_t) inLen);
 
   rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII
     (pCtxt, sign, inLen, bufIn, 0, inLen);
@@ -1169,7 +1169,7 @@
   size_t sigLength = (size_t) jSigLen;
 
   context = (crypto_ctx_t *) pCtxt;
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
       printf("NativeRSASignature.nativeFinal: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n",
              context, sign, bufSig, sigOfs, jSigLen);
       printBytes("Before: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen);
@@ -1182,7 +1182,7 @@
 
   freeContext(context);
   if (rv) {
-    if (DEBUG) {
+    if (J2UC_DEBUG) {
       printError("NativeRSASignature.nativeFinal", -1, rv);
       if (sigLength != jSigLen) {
         printf("NativeRSASignature.nativeFinal out sig len=%d\n", sigLength);
@@ -1247,7 +1247,7 @@
   size_t outLength = (size_t) jOutLen;
 
   pKey = (uchar_t *) keyValue;
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
     printf("NativeRSACipher.nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n",
            mech, encrypt, pKey, keyLength);
     printBytes("Before: in  = ", (unsigned char*) bufIn, jInLen);
@@ -1263,7 +1263,7 @@
       NULL, 0, (uchar_t *)bufIn, (size_t)jInLen,
       (uchar_t *)(bufOut + jOutOfs), &outLength);
   }
-  if (DEBUG) {
+  if (J2UC_DEBUG) {
     printError("NativeRSACipher.nativeAtomic", mech, rv);
     if (outLength != jOutLen) {
       printf("NativeRSACipher.nativeAtomic out len=%d\n", outLength);
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h	Tue Dec 13 02:04:23 2016 +0100
@@ -31,29 +31,6 @@
 extern "C" {
 #endif
 
-// used by nativeCrypto.c
-#ifdef _LIBUCRYPTO_H // workaround for Solaris bug; see 8157627
-#define CK_AES_CTR_PARAMS    crypto_ctr_params_t
-#define ulCounterBits    ct_ctr_bits
-#define cb        ct_cb
-
-#define CK_AES_CCM_PARAMS    crypto_ccm_params_t
-#define ulMACSize    cc_mac_size
-#define ulNonceSize    cc_nonce_size
-#define ulAuthDataSize    cc_auth_data_size
-#define ulDataSize    cc_data_size
-#define nonce        cc_nonce
-#define authData    cc_auth_data
-
-#define CK_AES_GCM_PARAMS    crypto_gcm_params_t
-#define pIv        gc_iv
-#define ulIvLen        gc_iv_len
-#define ulIvBits    gc_iv_bits
-#define pAAD        gc_aad
-#define ulAADLen    gc_aad_len
-#define ulTagBits    gc_tag_bits
-#endif
-
 // used by nativeCryptoMD.c
 #undef com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5
 #define com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5 1L
@@ -68,7 +45,7 @@
 #undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512
 #define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512 6L
 
-#define DEBUG 0
+#define J2UC_DEBUG 0
 
 #ifdef __cplusplus
 }
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCryptoMD.c	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCryptoMD.c	Tue Dec 13 02:04:23 2016 +0100
@@ -73,7 +73,7 @@
     }
     break;
   default:
-    if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech);
+    if (J2UC_DEBUG) printf("ERROR: Unsupported mech %i\n", mech);
   }
   return (jlong) pContext;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractPushPublisher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http;
+
+import java.util.Optional;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.Flow;
+import java.util.function.Consumer;
+
+/**
+ * A super class for PushPublisher implementation.
+ */
+abstract class AbstractPushPublisher<T> implements Flow.Publisher<T> {
+
+    static enum SubscriptionState { OPENED, DONE, CANCELLED };
+
+    public abstract void acceptData(Optional<T> item)
+        throws InterruptedException;
+
+    public abstract void acceptError(Throwable t);
+
+    public Consumer<Optional<T>> asDataConsumer() {
+        return this::consume;
+    }
+
+    void consume(Optional<T> item) {
+        try {
+            acceptData(item);
+        } catch (InterruptedException x) {
+            throw new CompletionException(x);
+        }
+    }
+
+        }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Implemented by classes that offer an asynchronous interface.
+ *
+ * PlainHttpConnection, AsyncSSLConnection AsyncSSLDelegate.
+ *
+ * setAsyncCallbacks() is called to set the callback for reading
+ * and error notification. Reads all happen on the selector thread, which
+ * must not block.
+ *
+ * Writing uses the same write() methods as used in blocking mode.
+ * Queues are employed on the writing side to buffer data while it is waiting
+ * to be sent. This strategy relies on HTTP/2 protocol flow control to stop
+ * outgoing queue from continually growing. Writes can be initiated by the
+ * calling thread, but if socket becomes full then the queue is emptied by
+ * the selector thread
+ */
+interface AsyncConnection {
+
+    /**
+     * Enables asynchronous sending and receiving mode. The given async
+     * receiver will receive all incoming data. asyncInput() will be called
+     * to trigger reads. asyncOutput() will be called to drive writes.
+     *
+     * The errorReceiver callback must be called when any fatal exception
+     * occurs. Connection is assumed to be closed afterwards.
+     */
+    void setAsyncCallbacks(Consumer<ByteBufferReference> asyncReceiver,
+                           Consumer<Throwable> errorReceiver,
+                           Supplier<ByteBufferReference> readBufferSupplier);
+
+
+
+    /**
+     * Does whatever is required to start reading. Usually registers
+     * an event with the selector thread.
+     */
+    void startReading();
+
+    /**
+     * In async mode, this method puts buffers at the end of the send queue.
+     * When in async mode, calling this method should later be followed by
+     * subsequent flushAsync invocation.
+     * That allows multiple threads to put buffers into the queue while some other
+     * thread is writing.
+     */
+    void writeAsync(ByteBufferReference[] buffers) throws IOException;
+
+    /**
+     * In async mode, this method may put buffers at the beginning of send queue,
+     * breaking frames sequence and allowing to write these buffers before other
+     * buffers in the queue.
+     * When in async mode, calling this method should later be followed by
+     * subsequent flushAsync invocation.
+     * That allows multiple threads to put buffers into the queue while some other
+     * thread is writing.
+     */
+    void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException;
+
+    /**
+     * This method should be called after any writeAsync/writeAsyncUnordered
+     * invocation.
+     * If there is a race to flushAsync from several threads one thread
+     * (race winner) capture flush operation and write the whole queue content.
+     * Other threads (race losers) exits from the method (not blocking)
+     * and continue execution.
+     */
+    void flushAsync() throws IOException;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncEvent.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.nio.channels.SelectableChannel;
+
+/**
+ * Event handling interface from HttpClientImpl's selector.
+ *
+ * If BLOCKING is set, then the channel will be put in blocking
+ * mode prior to handle() being called. If false, then it remains non-blocking.
+ *
+ * If REPEATING is set then the event is not cancelled after being posted.
+ */
+abstract class AsyncEvent {
+
+    public static final int BLOCKING = 0x1; // non blocking if not set
+    public static final int REPEATING = 0x2; // one off event if not set
+
+    protected final int flags;
+
+    AsyncEvent(int flags) {
+        this.flags = flags;
+    }
+
+    /** Returns the channel */
+    public abstract SelectableChannel channel();
+
+    /** Returns the selector interest op flags OR'd */
+    public abstract int interestOps();
+
+    /** Called when event occurs */
+    public abstract void handle();
+
+    /** Called when selector is shutting down. Abort all exchanges. */
+    public abstract void abort();
+
+    public boolean blocking() {
+        return (flags & BLOCKING) != 0;
+    }
+
+    public boolean repeating() {
+        return (flags & REPEATING) != 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.ExceptionallyCloseable;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * Asynchronous version of SSLConnection.
+ */
+class AsyncSSLConnection extends HttpConnection
+                         implements AsyncConnection, ExceptionallyCloseable {
+
+    final AsyncSSLDelegate sslDelegate;
+    final PlainHttpConnection delegate;
+
+    AsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) {
+        super(addr, client);
+        delegate = new PlainHttpConnection(addr, client);
+        sslDelegate = new AsyncSSLDelegate(delegate, client, ap);
+    }
+
+    @Override
+    synchronized void configureMode(Mode mode) throws IOException {
+        super.configureMode(mode);
+        delegate.configureMode(mode);
+    }
+
+    @Override
+    public void connect() throws IOException, InterruptedException {
+        delegate.connect();
+    }
+
+    @Override
+    public CompletableFuture<Void> connectAsync() {
+        return delegate.connectAsync();
+    }
+
+    @Override
+    boolean connected() {
+        return delegate.connected();
+    }
+
+    @Override
+    boolean isSecure() {
+        return true;
+    }
+
+    @Override
+    boolean isProxied() {
+        return false;
+    }
+
+    @Override
+    SocketChannel channel() {
+        return delegate.channel();
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return ConnectionPool.cacheKey(address, null);
+    }
+
+    @Override
+    long write(ByteBuffer[] buffers, int start, int number)
+        throws IOException
+    {
+        ByteBuffer[] bufs = Utils.reduce(buffers, start, number);
+        long n = Utils.remaining(bufs);
+        sslDelegate.writeAsync(ByteBufferReference.toReferences(bufs));
+        sslDelegate.flushAsync();
+        return n;
+    }
+
+    @Override
+    long write(ByteBuffer buffer) throws IOException {
+        long n = buffer.remaining();
+        sslDelegate.writeAsync(ByteBufferReference.toReferences(buffer));
+        sslDelegate.flushAsync();
+        return n;
+    }
+
+    @Override
+    public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+        assert getMode() == Mode.ASYNC;
+        sslDelegate.writeAsyncUnordered(buffers);
+    }
+
+    @Override
+    public void writeAsync(ByteBufferReference[] buffers) throws IOException {
+        assert getMode() == Mode.ASYNC;
+        sslDelegate.writeAsync(buffers);
+    }
+
+    @Override
+    public void flushAsync() throws IOException {
+        sslDelegate.flushAsync();
+    }
+
+    @Override
+    public void closeExceptionally(Throwable cause) {
+        Utils.close(cause, sslDelegate, delegate.channel());
+    }
+
+    @Override
+    public void close() {
+        Utils.close(sslDelegate, delegate.channel());
+    }
+
+    @Override
+    void shutdownInput() throws IOException {
+        delegate.channel().shutdownInput();
+    }
+
+    @Override
+    void shutdownOutput() throws IOException {
+        delegate.channel().shutdownOutput();
+    }
+
+    @Override
+    public void setAsyncCallbacks(Consumer<ByteBufferReference> asyncReceiver,
+                                  Consumer<Throwable> errorReceiver,
+                                  Supplier<ByteBufferReference> readBufferSupplier) {
+        sslDelegate.setAsyncCallbacks(asyncReceiver, errorReceiver, readBufferSupplier);
+        delegate.setAsyncCallbacks(sslDelegate::asyncReceive, errorReceiver, sslDelegate::getNetBuffer);
+    }
+
+    // Blocking read functions not used here
+
+    @Override
+    protected ByteBuffer readImpl() throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    protected int readImpl(ByteBuffer buffer) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    CompletableFuture<Void> whenReceivingResponse() {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public void startReading() {
+        delegate.startReading();
+        sslDelegate.startReading();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLDelegate.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import static javax.net.ssl.SSLEngineResult.Status.*;
+import javax.net.ssl.*;
+
+import jdk.incubator.http.internal.common.AsyncWriteQueue;
+import jdk.incubator.http.internal.common.ByteBufferPool;
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.Queue;
+import jdk.incubator.http.internal.common.Utils;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
+import jdk.incubator.http.internal.common.ExceptionallyCloseable;
+
+/**
+ * Asynchronous wrapper around SSLEngine. send and receive is fully non
+ * blocking. When handshaking is required, a thread is created to perform
+ * the handshake and application level sends do not take place during this time.
+ *
+ * Is implemented using queues and functions operating on the receiving end
+ * of each queue.
+ *
+ * Application writes to:
+ *        ||
+ *        \/
+ *     appOutputQ
+ *        ||
+ *        \/
+ * appOutputQ read by "upperWrite" method which does SSLEngine.wrap
+ * and does async write to PlainHttpConnection
+ *
+ * Reading side is as follows
+ * --------------------------
+ *
+ * "upperRead" method reads off channelInputQ and calls SSLEngine.unwrap and
+ * when decrypted data is returned, it is passed to the user's Consumer<ByteBuffer>
+ *        /\
+ *        ||
+ *     channelInputQ
+ *        /\
+ *        ||
+ * "lowerRead" method puts buffers into channelInputQ. It is invoked from
+ * OP_READ events from the selector.
+ *
+ * Whenever handshaking is required, the doHandshaking() method is called
+ * which creates a thread to complete the handshake. It takes over the
+ * channelInputQ from upperRead, and puts outgoing packets on channelOutputQ.
+ * Selector events are delivered to lowerRead and lowerWrite as normal.
+ *
+ * Errors
+ *
+ * Any exception thrown by the engine or channel, causes all Queues to be closed
+ * the channel to be closed, and the error is reported to the user's
+ * Consumer<Throwable>
+ */
+class AsyncSSLDelegate implements ExceptionallyCloseable, AsyncConnection {
+
+    // outgoing buffers put in this queue first and may remain here
+    // while SSL handshaking happening.
+    final AsyncWriteQueue appOutputQ = new AsyncWriteQueue(this::upperWrite);
+
+    // queue of wrapped ByteBuffers waiting to be sent on socket channel
+    //final Queue<ByteBuffer> channelOutputQ;
+
+    // Bytes read into this queue before being unwrapped. Backup on this
+    // Q should only happen when the engine is stalled due to delegated tasks
+    final Queue<ByteBufferReference> channelInputQ;
+
+    // input occurs through the read() method which is expected to be called
+    // when the selector signals some data is waiting to be read. All incoming
+    // handshake data is handled in this method, which means some calls to
+    // read() may return zero bytes of user data. This is not a sign of spinning,
+    // just that the handshake mechanics are being executed.
+
+    final SSLEngine engine;
+    final SSLParameters sslParameters;
+    //final SocketChannel chan;
+    final HttpConnection lowerOutput;
+    final HttpClientImpl client;
+    // should be volatile to provide proper synchronization(visibility) action
+    volatile Consumer<ByteBufferReference> asyncReceiver;
+    volatile Consumer<Throwable> errorHandler;
+
+    // Locks.
+    final Object reader = new Object();
+    // synchronizing handshake state
+    final Semaphore handshaker = new Semaphore(1);
+    // flag set when frame or writer is blocked waiting for handshake to finish
+    //boolean writerBlocked;
+    //boolean readerBlocked;
+
+    // alpn[] may be null. upcall is callback which receives incoming decoded bytes off socket
+
+    AsyncSSLDelegate(HttpConnection lowerOutput, HttpClientImpl client, String[] alpn)
+    {
+        SSLContext context = client.sslContext();
+        //channelOutputQ = new Queue<>();
+        //channelOutputQ.registerPutCallback(this::lowerWrite);
+        engine = context.createSSLEngine();
+        engine.setUseClientMode(true);
+        SSLParameters sslp = client.sslParameters()
+                                   .orElseGet(context::getSupportedSSLParameters);
+        sslParameters = Utils.copySSLParameters(sslp);
+        if (alpn != null) {
+            sslParameters.setApplicationProtocols(alpn);
+        }
+        logParams(sslParameters);
+        engine.setSSLParameters(sslParameters);
+        this.lowerOutput = lowerOutput;
+        this.client = client;
+        this.channelInputQ = new Queue<>();
+        this.channelInputQ.registerPutCallback(this::upperRead);
+    }
+
+    @Override
+    public void writeAsync(ByteBufferReference[] src) throws IOException {
+        appOutputQ.put(src);
+    }
+
+    @Override
+    public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+        appOutputQ.putFirst(buffers);
+    }
+
+    @Override
+    public void flushAsync() throws IOException {
+        if (appOutputQ.flush()) {
+            lowerOutput.flushAsync();
+        }
+    }
+
+    @Override
+    public void closeExceptionally(Throwable t) {
+        Utils.close(t, appOutputQ, channelInputQ, lowerOutput);
+    }
+
+    @Override
+    public void close() {
+        Utils.close(appOutputQ, channelInputQ, lowerOutput);
+    }
+
+    // The code below can be uncommented to shake out
+    // the implementation by inserting random delays and trigger
+    // handshake in the SelectorManager thread (upperRead)
+    // static final java.util.Random random =
+    //    new java.util.Random(System.currentTimeMillis());
+
+    /**
+     * Attempts to wrap buffers from appOutputQ and place them on the
+     * channelOutputQ for writing. If handshaking is happening, then the
+     * process stalls and last buffers taken off the appOutputQ are put back
+     * into it until handshaking completes.
+     *
+     * This same method is called to try and resume output after a blocking
+     * handshaking operation has completed.
+     */
+    private void upperWrite(ByteBufferReference[] refs, AsyncWriteQueue delayCallback) {
+        // currently delayCallback is not used. Use it when it's needed to execute handshake in another thread.
+        try {
+            ByteBuffer[] buffers = ByteBufferReference.toBuffers(refs);
+            int bytes = Utils.remaining(buffers);
+            while (bytes > 0) {
+                EngineResult r = wrapBuffers(buffers);
+                int bytesProduced = r.bytesProduced();
+                int bytesConsumed = r.bytesConsumed();
+                bytes -= bytesConsumed;
+                if (bytesProduced > 0) {
+                    lowerOutput.writeAsync(new ByteBufferReference[]{r.destBuffer});
+                }
+
+                // The code below can be uncommented to shake out
+                // the implementation by inserting random delays and trigger
+                // handshake in the SelectorManager thread (upperRead)
+
+                // int sleep = random.nextInt(100);
+                // if (sleep > 20) {
+                //   Thread.sleep(sleep);
+                // }
+
+                // handshaking is happening or is needed
+                if (r.handshaking()) {
+                    Log.logTrace("Write: needs handshake");
+                    doHandshakeNow("Write");
+                }
+            }
+            ByteBufferReference.clear(refs);
+        } catch (Throwable t) {
+            closeExceptionally(t);
+            errorHandler.accept(t);
+        }
+    }
+
+    private void startHandshake(String tag) {
+        Runnable run = () -> {
+            try {
+                doHandshakeNow(tag);
+            } catch (Throwable t) {
+                Log.logTrace("{0}: handshake failed: {1}", tag, t);
+                closeExceptionally(t);
+                errorHandler.accept(t);
+            }
+        };
+        client.executor().execute(run);
+    }
+
+    private void doHandshakeNow(String tag)
+        throws IOException, InterruptedException
+    {
+        handshaker.acquire();
+        try {
+            channelInputQ.registerPutCallback(null);
+            lowerOutput.flushAsync();
+            Log.logTrace("{0}: Starting handshake...", tag);
+            doHandshakeImpl();
+            Log.logTrace("{0}: Handshake completed", tag);
+            channelInputQ.registerPutCallback(this::upperRead);
+        } finally {
+            handshaker.release();
+        }
+    }
+
+     /**
+     * Executes entire handshake in calling thread.
+     * Returns after handshake is completed or error occurs
+     */
+    private void doHandshakeImpl() throws IOException {
+        while (true) {
+            SSLEngineResult.HandshakeStatus status = engine.getHandshakeStatus();
+            switch(status) {
+                case NEED_TASK: {
+                    List<Runnable> tasks = obtainTasks();
+                    for (Runnable task : tasks) {
+                        task.run();
+                    }
+                } break;
+                case NEED_WRAP:
+                    handshakeWrapAndSend();
+                    break;
+                case NEED_UNWRAP: case NEED_UNWRAP_AGAIN:
+                    handshakeReceiveAndUnWrap();
+                    break;
+                case FINISHED: case NOT_HANDSHAKING:
+                    return;
+                default:
+                    throw new InternalError("Unexpected Handshake Status: "
+                                             + status);
+            }
+        }
+    }
+
+    // acknowledge a received CLOSE request from peer
+    void doClosure() throws IOException {
+        //while (!wrapAndSend(emptyArray))
+            //;
+    }
+
+    List<Runnable> obtainTasks() {
+        List<Runnable> l = new ArrayList<>();
+        Runnable r;
+        while ((r = engine.getDelegatedTask()) != null) {
+            l.add(r);
+        }
+        return l;
+    }
+
+    @Override
+    public void setAsyncCallbacks(Consumer<ByteBufferReference> asyncReceiver,
+                                  Consumer<Throwable> errorReceiver,
+                                  Supplier<ByteBufferReference> readBufferSupplier) {
+        this.asyncReceiver = asyncReceiver;
+        this.errorHandler = errorReceiver;
+        // readBufferSupplier is not used,
+        // because of AsyncSSLDelegate has its own appBufferPool
+    }
+
+    @Override
+    public void startReading() {
+        // maybe this class does not need to implement AsyncConnection
+    }
+
+    static class EngineResult {
+        final SSLEngineResult result;
+        final ByteBufferReference destBuffer;
+
+
+        // normal result
+        EngineResult(SSLEngineResult result) {
+            this(result, null);
+        }
+
+        EngineResult(SSLEngineResult result, ByteBufferReference destBuffer) {
+            this.result = result;
+            this.destBuffer = destBuffer;
+        }
+
+        boolean handshaking() {
+            SSLEngineResult.HandshakeStatus s = result.getHandshakeStatus();
+            return s != FINISHED && s != NOT_HANDSHAKING;
+        }
+
+        int bytesConsumed() {
+            return result.bytesConsumed();
+        }
+
+        int bytesProduced() {
+            return result.bytesProduced();
+        }
+
+        SSLEngineResult.HandshakeStatus handshakeStatus() {
+            return result.getHandshakeStatus();
+        }
+
+        SSLEngineResult.Status status() {
+            return result.getStatus();
+        }
+    }
+
+    EngineResult handshakeWrapAndSend() throws IOException {
+        EngineResult r = wrapBuffer(Utils.EMPTY_BYTEBUFFER);
+        if (r.bytesProduced() > 0) {
+            lowerOutput.writeAsync(new ByteBufferReference[]{r.destBuffer});
+            lowerOutput.flushAsync();
+        }
+        return r;
+    }
+
+    // called during handshaking. It blocks until a complete packet
+    // is available, unwraps it and returns.
+    void handshakeReceiveAndUnWrap() throws IOException {
+        ByteBufferReference ref = channelInputQ.take();
+        while (true) {
+            // block waiting for input
+            EngineResult r = unwrapBuffer(ref.get());
+            SSLEngineResult.Status status = r.status();
+            if (status == BUFFER_UNDERFLOW) {
+                // wait for another buffer to arrive
+                ByteBufferReference ref1 = channelInputQ.take();
+                ref = combine (ref, ref1);
+                continue;
+            }
+            // OK
+            // theoretically possible we could receive some user data
+            if (r.bytesProduced() > 0) {
+                asyncReceiver.accept(r.destBuffer);
+            } else {
+                r.destBuffer.clear();
+            }
+            // it is also possible that a delegated task could be needed
+            // even though they are handled in the calling function
+            if (r.handshakeStatus() == NEED_TASK) {
+                obtainTasks().stream().forEach((task) -> task.run());
+            }
+
+            if (!ref.get().hasRemaining()) {
+                ref.clear();
+                return;
+            }
+        }
+    }
+
+    EngineResult wrapBuffer(ByteBuffer src) throws SSLException {
+        ByteBuffer[] bufs = new ByteBuffer[1];
+        bufs[0] = src;
+        return wrapBuffers(bufs);
+    }
+
+    private final ByteBufferPool netBufferPool = new ByteBufferPool();
+    private final ByteBufferPool appBufferPool = new ByteBufferPool();
+
+    /**
+     * provides buffer of sslEngine@getPacketBufferSize().
+     * used for encrypted buffers after wrap or before unwrap.
+     * @return ByteBufferReference
+     */
+    public ByteBufferReference getNetBuffer() {
+        return netBufferPool.get(engine.getSession().getPacketBufferSize());
+    }
+
+    /**
+     * provides buffer of sslEngine@getApplicationBufferSize().
+     * @return ByteBufferReference
+     */
+    private ByteBufferReference getAppBuffer() {
+        return appBufferPool.get(engine.getSession().getApplicationBufferSize());
+    }
+
+    EngineResult wrapBuffers(ByteBuffer[] src) throws SSLException {
+        ByteBufferReference dst = getNetBuffer();
+        while (true) {
+            SSLEngineResult sslResult = engine.wrap(src, dst.get());
+            switch (sslResult.getStatus()) {
+                case BUFFER_OVERFLOW:
+                    // Shouldn't happen. We allocated buffer with packet size
+                    // get it again if net buffer size was changed
+                    dst = getNetBuffer();
+                    break;
+                case CLOSED:
+                case OK:
+                    dst.get().flip();
+                    return new EngineResult(sslResult, dst);
+                case BUFFER_UNDERFLOW:
+                    // Shouldn't happen.  Doesn't returns when wrap()
+                    // underflow handled externally
+                    return new EngineResult(sslResult);
+                default:
+                    assert false;
+            }
+        }
+    }
+
+    EngineResult unwrapBuffer(ByteBuffer srcbuf) throws IOException {
+        ByteBufferReference dst = getAppBuffer();
+        while (true) {
+            SSLEngineResult sslResult = engine.unwrap(srcbuf, dst.get());
+            switch (sslResult.getStatus()) {
+                case BUFFER_OVERFLOW:
+                    // may happen only if app size buffer was changed.
+                    // get it again if app buffer size changed
+                    dst = getAppBuffer();
+                    break;
+                case CLOSED:
+                    doClosure();
+                    throw new IOException("Engine closed");
+                case BUFFER_UNDERFLOW:
+                    dst.clear();
+                    return new EngineResult(sslResult);
+                case OK:
+                     dst.get().flip();
+                     return new EngineResult(sslResult, dst);
+            }
+        }
+    }
+
+    /**
+     * Asynchronous read input. Call this when selector fires.
+     * Unwrap done in upperRead because it also happens in
+     * doHandshake() when handshake taking place
+     */
+    public void asyncReceive(ByteBufferReference buffer) {
+        try {
+            channelInputQ.put(buffer);
+        } catch (Throwable t) {
+            closeExceptionally(t);
+            errorHandler.accept(t);
+        }
+    }
+
+    private ByteBufferReference pollInput() throws IOException {
+        return channelInputQ.poll();
+    }
+
+    private ByteBufferReference pollInput(ByteBufferReference next) throws IOException {
+        return next == null ? channelInputQ.poll() : next;
+    }
+
+    public void upperRead() {
+        ByteBufferReference src;
+        ByteBufferReference next = null;
+        synchronized (reader) {
+            try {
+                src = pollInput();
+                if (src == null) {
+                    return;
+                }
+                while (true) {
+                    EngineResult r = unwrapBuffer(src.get());
+                    switch (r.result.getStatus()) {
+                        case BUFFER_UNDERFLOW:
+                            // Buffer too small. Need to combine with next buf
+                            next = pollInput(next);
+                            if (next == null) {
+                                // no data available.
+                                // push buffer back until more data available
+                                channelInputQ.pushback(src);
+                                return;
+                            } else {
+                                src = shift(src, next);
+                                if (!next.get().hasRemaining()) {
+                                    next.clear();
+                                    next = null;
+                                }
+                            }
+                            break;
+                        case OK:
+                            // check for any handshaking work
+                            if (r.handshaking()) {
+                                // handshaking is happening or is needed
+                                // so we put the buffer back on Q to process again
+                                // later.
+                                Log.logTrace("Read: needs handshake");
+                                channelInputQ.pushback(src);
+                                startHandshake("Read");
+                                return;
+                            }
+                            asyncReceiver.accept(r.destBuffer);
+                    }
+                    if (src.get().hasRemaining()) {
+                        continue;
+                    }
+                    src.clear();
+                    src = pollInput(next);
+                    next = null;
+                    if (src == null) {
+                        return;
+                    }
+                }
+            } catch (Throwable t) {
+                closeExceptionally(t);
+                errorHandler.accept(t);
+            }
+        }
+    }
+
+    ByteBufferReference shift(ByteBufferReference ref1, ByteBufferReference ref2) {
+        ByteBuffer buf1 = ref1.get();
+        if (buf1.capacity() < engine.getSession().getPacketBufferSize()) {
+            ByteBufferReference newRef = getNetBuffer();
+            ByteBuffer newBuf = newRef.get();
+            newBuf.put(buf1);
+            buf1 = newBuf;
+            ref1.clear();
+            ref1 = newRef;
+        } else {
+            buf1.compact();
+        }
+        ByteBuffer buf2 = ref2.get();
+        Utils.copy(buf2, buf1, Math.min(buf1.remaining(), buf2.remaining()));
+        buf1.flip();
+        return ref1;
+    }
+
+
+    ByteBufferReference combine(ByteBufferReference ref1, ByteBufferReference ref2) {
+        ByteBuffer buf1 = ref1.get();
+        ByteBuffer buf2 = ref2.get();
+        int avail1 = buf1.capacity() - buf1.remaining();
+        if (buf2.remaining() < avail1) {
+            buf1.compact();
+            buf1.put(buf2);
+            buf1.flip();
+            ref2.clear();
+            return ref1;
+        }
+        int newsize = buf1.remaining() + buf2.remaining();
+        ByteBuffer newbuf = ByteBuffer.allocate(newsize); // getting rid of buffer pools
+        newbuf.put(buf1);
+        newbuf.put(buf2);
+        newbuf.flip();
+        ref1.clear();
+        ref2.clear();
+        return ByteBufferReference.of(newbuf);
+    }
+
+    SSLParameters getSSLParameters() {
+        return sslParameters;
+    }
+
+    static void logParams(SSLParameters p) {
+        if (!Log.ssl()) {
+            return;
+        }
+
+        if (p == null) {
+            Log.logSSL("SSLParameters: Null params");
+            return;
+        }
+
+        final StringBuilder sb = new StringBuilder("SSLParameters:");
+        final List<Object> params = new ArrayList<>();
+        if (p.getCipherSuites() != null) {
+            for (String cipher : p.getCipherSuites()) {
+                sb.append("\n    cipher: {")
+                  .append(params.size()).append("}");
+                params.add(cipher);
+            }
+        }
+
+        // SSLParameters.getApplicationProtocols() can't return null
+        for (String approto : p.getApplicationProtocols()) {
+            sb.append("\n    application protocol: {")
+              .append(params.size()).append("}");
+            params.add(approto);
+        }
+
+        if (p.getProtocols() != null) {
+            for (String protocol : p.getProtocols()) {
+                sb.append("\n    protocol: {")
+                  .append(params.size()).append("}");
+                params.add(protocol);
+            }
+        }
+
+        if (p.getServerNames() != null) {
+            for (SNIServerName sname : p.getServerNames()) {
+                 sb.append("\n    server name: {")
+                  .append(params.size()).append("}");
+                params.add(sname.toString());
+            }
+        }
+        sb.append('\n');
+
+        Log.logSSL(sb.toString(), params.toArray());
+    }
+
+    String getSessionInfo() {
+        StringBuilder sb = new StringBuilder();
+        String application = engine.getApplicationProtocol();
+        SSLSession sess = engine.getSession();
+        String cipher = sess.getCipherSuite();
+        String protocol = sess.getProtocol();
+        sb.append("Handshake complete alpn: ")
+          .append(application)
+          .append(", Cipher: ")
+          .append(cipher)
+          .append(", Protocol: ")
+          .append(protocol);
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AuthenticationFilter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.PasswordAuthentication;
+import java.net.URI;
+import java.net.InetSocketAddress;
+import java.net.URISyntaxException;
+import java.util.Base64;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.WeakHashMap;
+import jdk.incubator.http.internal.common.Utils;
+import static java.net.Authenticator.RequestorType.PROXY;
+import static java.net.Authenticator.RequestorType.SERVER;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
+/**
+ * Implementation of Http Basic authentication.
+ */
+class AuthenticationFilter implements HeaderFilter {
+    volatile MultiExchange<?,?> exchange;
+    private static final Base64.Encoder encoder = Base64.getEncoder();
+
+    static final int DEFAULT_RETRY_LIMIT = 3;
+
+    static final int retry_limit = Utils.getIntegerNetProperty(
+            "jdk.httpclient.auth.retrylimit", DEFAULT_RETRY_LIMIT);
+
+    static final int UNAUTHORIZED = 401;
+    static final int PROXY_UNAUTHORIZED = 407;
+
+    private PasswordAuthentication getCredentials(String header,
+                                                  boolean proxy,
+                                                  HttpRequestImpl req)
+        throws IOException
+    {
+        HttpClientImpl client = exchange.client();
+        java.net.Authenticator auth =
+                client.authenticator()
+                      .orElseThrow(() -> new IOException("No authenticator set"));
+        URI uri = req.uri();
+        HeaderParser parser = new HeaderParser(header);
+        String authscheme = parser.findKey(0);
+
+        String realm = parser.findValue("realm");
+        java.net.Authenticator.RequestorType rtype = proxy ? PROXY : SERVER;
+
+        // needs to be instance method in Authenticator
+        return auth.requestPasswordAuthenticationInstance(uri.getHost(),
+                                                          null,
+                                                          uri.getPort(),
+                                                          uri.getScheme(),
+                                                          realm,
+                                                          authscheme,
+                                                          uri.toURL(),
+                                                          rtype
+        );
+    }
+
+    private URI getProxyURI(HttpRequestImpl r) {
+        InetSocketAddress proxy = r.proxy(exchange.client());
+        if (proxy == null) {
+            return null;
+        }
+
+        // our own private scheme for proxy URLs
+        // eg. proxy.http://host:port/
+        String scheme = "proxy." + r.uri().getScheme();
+        try {
+            return new URI(scheme,
+                           null,
+                           proxy.getHostString(),
+                           proxy.getPort(),
+                           null,
+                           null,
+                           null);
+        } catch (URISyntaxException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    @Override
+    public void request(HttpRequestImpl r, MultiExchange<?,?> e) throws IOException {
+        // use preemptive authentication if an entry exists.
+        Cache cache = getCache(e);
+        this.exchange = e;
+
+        // Proxy
+        if (exchange.proxyauth == null) {
+            URI proxyURI = getProxyURI(r);
+            if (proxyURI != null) {
+                CacheEntry ca = cache.get(proxyURI, true);
+                if (ca != null) {
+                    exchange.proxyauth = new AuthInfo(true, ca.scheme, null, ca);
+                    addBasicCredentials(r, true, ca.value);
+                }
+            }
+        }
+
+        // Server
+        if (exchange.serverauth == null) {
+            CacheEntry ca = cache.get(r.uri(), false);
+            if (ca != null) {
+                exchange.serverauth = new AuthInfo(true, ca.scheme, null, ca);
+                addBasicCredentials(r, false, ca.value);
+            }
+        }
+    }
+
+    // TODO: refactor into per auth scheme class
+    private static void addBasicCredentials(HttpRequestImpl r,
+                                            boolean proxy,
+                                            PasswordAuthentication pw) {
+        String hdrname = proxy ? "Proxy-Authorization" : "Authorization";
+        StringBuilder sb = new StringBuilder(128);
+        sb.append(pw.getUserName()).append(':').append(pw.getPassword());
+        String s = encoder.encodeToString(sb.toString().getBytes(ISO_8859_1));
+        String value = "Basic " + s;
+        r.setSystemHeader(hdrname, value);
+    }
+
+    // Information attached to a HttpRequestImpl relating to authentication
+    static class AuthInfo {
+        final boolean fromcache;
+        final String scheme;
+        int retries;
+        PasswordAuthentication credentials; // used in request
+        CacheEntry cacheEntry; // if used
+
+        AuthInfo(boolean fromcache,
+                 String scheme,
+                 PasswordAuthentication credentials) {
+            this.fromcache = fromcache;
+            this.scheme = scheme;
+            this.credentials = credentials;
+            this.retries = 1;
+        }
+
+        AuthInfo(boolean fromcache,
+                 String scheme,
+                 PasswordAuthentication credentials,
+                 CacheEntry ca) {
+            this(fromcache, scheme, credentials);
+            assert credentials == null || (ca != null && ca.value == null);
+            cacheEntry = ca;
+        }
+
+        AuthInfo retryWithCredentials(PasswordAuthentication pw) {
+            // If the info was already in the cache we need to create a new
+            // instance with fromCache==false so that it's put back in the
+            // cache if authentication succeeds
+            AuthInfo res = fromcache ? new AuthInfo(false, scheme, pw) : this;
+            res.credentials = Objects.requireNonNull(pw);
+            res.retries = retries;
+            return res;
+        }
+
+    }
+
+    @Override
+    public HttpRequestImpl response(Response r) throws IOException {
+        Cache cache = getCache(exchange);
+        int status = r.statusCode();
+        HttpHeaders hdrs = r.headers();
+        HttpRequestImpl req = r.request();
+
+        if (status != UNAUTHORIZED && status != PROXY_UNAUTHORIZED) {
+            // check if any authentication succeeded for first time
+            if (exchange.serverauth != null && !exchange.serverauth.fromcache) {
+                AuthInfo au = exchange.serverauth;
+                cache.store(au.scheme, req.uri(), false, au.credentials);
+            }
+            if (exchange.proxyauth != null && !exchange.proxyauth.fromcache) {
+                AuthInfo au = exchange.proxyauth;
+                cache.store(au.scheme, req.uri(), false, au.credentials);
+            }
+            return null;
+        }
+
+        boolean proxy = status == PROXY_UNAUTHORIZED;
+        String authname = proxy ? "Proxy-Authenticate" : "WWW-Authenticate";
+        String authval = hdrs.firstValue(authname).orElseThrow(() -> {
+            return new IOException("Invalid auth header");
+        });
+        HeaderParser parser = new HeaderParser(authval);
+        String scheme = parser.findKey(0);
+
+        // TODO: Need to generalise from Basic only. Delegate to a provider class etc.
+
+        if (!scheme.equalsIgnoreCase("Basic")) {
+            return null;   // error gets returned to app
+        }
+
+        String realm = parser.findValue("realm");
+        AuthInfo au = proxy ? exchange.proxyauth : exchange.serverauth;
+        if (au == null) {
+            PasswordAuthentication pw = getCredentials(authval, proxy, req);
+            if (pw == null) {
+                throw new IOException("No credentials provided");
+            }
+            // No authentication in request. Get credentials from user
+            au = new AuthInfo(false, "Basic", pw);
+            if (proxy) {
+                exchange.proxyauth = au;
+            } else {
+                exchange.serverauth = au;
+            }
+            addBasicCredentials(req, proxy, pw);
+            return req;
+        } else if (au.retries > retry_limit) {
+            throw new IOException("too many authentication attempts. Limit: " +
+                    Integer.toString(retry_limit));
+        } else {
+            // we sent credentials, but they were rejected
+            if (au.fromcache) {
+                cache.remove(au.cacheEntry);
+            }
+            // try again
+            PasswordAuthentication pw = getCredentials(authval, proxy, req);
+            if (pw == null) {
+                throw new IOException("No credentials provided");
+            }
+            au = au.retryWithCredentials(pw);
+            if (proxy) {
+                exchange.proxyauth = au;
+            } else {
+                exchange.serverauth = au;
+            }
+            addBasicCredentials(req, proxy, au.credentials);
+            au.retries++;
+            return req;
+        }
+    }
+
+    // Use a WeakHashMap to make it possible for the HttpClient to
+    // be garbaged collected when no longer referenced.
+    static final WeakHashMap<HttpClientImpl,Cache> caches = new WeakHashMap<>();
+
+    static synchronized Cache getCache(MultiExchange<?,?> exchange) {
+        HttpClientImpl client = exchange.client();
+        Cache c = caches.get(client);
+        if (c == null) {
+            c = new Cache();
+            caches.put(client, c);
+        }
+        return c;
+    }
+
+    // Note: Make sure that Cache and CacheEntry do not keep any strong
+    //       reference to the HttpClient: it would prevent the client being
+    //       GC'ed when no longer referenced.
+    static class Cache {
+        final LinkedList<CacheEntry> entries = new LinkedList<>();
+
+        synchronized CacheEntry get(URI uri, boolean proxy) {
+            for (CacheEntry entry : entries) {
+                if (entry.equalsKey(uri, proxy)) {
+                    return entry;
+                }
+            }
+            return null;
+        }
+
+        synchronized void remove(String authscheme, URI domain, boolean proxy) {
+            for (CacheEntry entry : entries) {
+                if (entry.equalsKey(domain, proxy)) {
+                    entries.remove(entry);
+                }
+            }
+        }
+
+        synchronized void remove(CacheEntry entry) {
+            entries.remove(entry);
+        }
+
+        synchronized void store(String authscheme,
+                                URI domain,
+                                boolean proxy,
+                                PasswordAuthentication value) {
+            remove(authscheme, domain, proxy);
+            entries.add(new CacheEntry(authscheme, domain, proxy, value));
+        }
+    }
+
+    static class CacheEntry {
+        final String root;
+        final String scheme;
+        final boolean proxy;
+        final PasswordAuthentication value;
+
+        CacheEntry(String authscheme,
+                   URI uri,
+                   boolean proxy,
+                   PasswordAuthentication value) {
+            this.scheme = authscheme;
+            this.root = uri.resolve(".").toString(); // remove extraneous components
+            this.proxy = proxy;
+            this.value = value;
+        }
+
+        public PasswordAuthentication value() {
+            return value;
+        }
+
+        public boolean equalsKey(URI uri, boolean proxy) {
+            if (this.proxy != proxy) {
+                return false;
+            }
+            String other = uri.toString();
+            return other.startsWith(root);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/BlockingPushPublisher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Optional;
+import java.util.concurrent.Flow;
+import jdk.incubator.http.internal.common.Log;
+
+/**
+ * A Publisher which is assumed to run in its own thread.
+ *
+ * acceptData() may therefore block while waiting for subscriber demand
+ */
+class BlockingPushPublisher<T> extends AbstractPushPublisher<T> {
+    volatile Subscription subscription;
+    volatile Flow.Subscriber<? super T> subscriber;
+    volatile SubscriptionState state;
+    long demand;
+
+    @Override
+    public void subscribe(Flow.Subscriber<? super T> subscriber) {
+        state = SubscriptionState.OPENED;
+        subscription = new Subscription(subscriber);
+        subscriber.onSubscribe(subscription);
+    }
+
+    /**
+     * Entry point for supplying items to publisher. This call will block
+     * when no demand available.
+     */
+    @Override
+    public void acceptData(Optional<T> item) throws InterruptedException {
+        SubscriptionState s = this.state;
+
+        // do not use switch(this.state): this.state could be null.
+        if (s == SubscriptionState.CANCELLED) return;
+        if (s == SubscriptionState.DONE) {
+            throw new IllegalStateException("subscription complete");
+        }
+
+        if (!item.isPresent()) {
+            subscriber.onComplete();
+            this.state = SubscriptionState.DONE;
+        } else {
+            obtainPermit();
+            if (this.state == SubscriptionState.CANCELLED) return;
+            subscriber.onNext(item.get());
+        }
+    }
+
+    /**
+     * Terminates the publisher with given exception.
+     */
+    @Override
+    public void acceptError(Throwable t) {
+        if (this.state != SubscriptionState.OPENED) {
+            Log.logError(t);
+            return;
+        }
+        subscriber.onError(t);
+        cancel();
+    }
+
+    private synchronized void obtainPermit() throws InterruptedException {
+        while (demand == 0) {
+            wait();
+        }
+        if (this.state == SubscriptionState.DONE) {
+            throw new IllegalStateException("subscription complete");
+        }
+        demand --;
+    }
+
+    synchronized void addPermits(long n) {
+        long old = demand;
+        demand += n;
+        if (old == 0) {
+            notifyAll();
+        }
+    }
+
+    synchronized void cancel() {
+        this.state = SubscriptionState.CANCELLED;
+        notifyAll();
+    }
+
+    private class Subscription implements Flow.Subscription {
+
+        Subscription(Flow.Subscriber<? super T> subscriber) {
+            BlockingPushPublisher.this.subscriber = subscriber;
+        }
+
+        @Override
+        public void request(long n) {
+            addPermits(n);
+        }
+
+        @Override
+        public void cancel() {
+            BlockingPushPublisher.this.cancel();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ConnectionPool.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Objects;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * Http 1.1 connection pool.
+ */
+final class ConnectionPool {
+
+    static final long KEEP_ALIVE = Utils.getIntegerNetProperty(
+            "jdk.httpclient.keepalive.timeout", 1200); // seconds
+
+    // Pools of idle connections
+
+    final HashMap<CacheKey,LinkedList<HttpConnection>> plainPool;
+    final HashMap<CacheKey,LinkedList<HttpConnection>> sslPool;
+    CacheCleaner cleaner;
+
+    /**
+     * Entries in connection pool are keyed by destination address and/or
+     * proxy address:
+     * case 1: plain TCP not via proxy (destination only)
+     * case 2: plain TCP via proxy (proxy only)
+     * case 3: SSL not via proxy (destination only)
+     * case 4: SSL over tunnel (destination and proxy)
+     */
+    static class CacheKey {
+        final InetSocketAddress proxy;
+        final InetSocketAddress destination;
+
+        CacheKey(InetSocketAddress destination, InetSocketAddress proxy) {
+            this.proxy = proxy;
+            this.destination = destination;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final CacheKey other = (CacheKey) obj;
+            if (!Objects.equals(this.proxy, other.proxy)) {
+                return false;
+            }
+            if (!Objects.equals(this.destination, other.destination)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(proxy, destination);
+        }
+    }
+
+    static class ExpiryEntry {
+        final HttpConnection connection;
+        final long expiry; // absolute time in seconds of expiry time
+        ExpiryEntry(HttpConnection connection, long expiry) {
+            this.connection = connection;
+            this.expiry = expiry;
+        }
+    }
+
+    final LinkedList<ExpiryEntry> expiryList;
+
+    /**
+     * There should be one of these per HttpClient.
+     */
+    ConnectionPool() {
+        plainPool = new HashMap<>();
+        sslPool = new HashMap<>();
+        expiryList = new LinkedList<>();
+    }
+
+    void start() {
+    }
+
+    static CacheKey cacheKey(InetSocketAddress destination,
+                             InetSocketAddress proxy) {
+        return new CacheKey(destination, proxy);
+    }
+
+    synchronized HttpConnection getConnection(boolean secure,
+                                              InetSocketAddress addr,
+                                              InetSocketAddress proxy) {
+        CacheKey key = new CacheKey(addr, proxy);
+        HttpConnection c = secure ? findConnection(key, sslPool)
+                                  : findConnection(key, plainPool);
+        //System.out.println ("getConnection returning: " + c);
+        return c;
+    }
+
+    /**
+     * Returns the connection to the pool.
+     */
+    synchronized void returnToPool(HttpConnection conn) {
+        if (conn instanceof PlainHttpConnection) {
+            putConnection(conn, plainPool);
+        } else {
+            putConnection(conn, sslPool);
+        }
+        addToExpiryList(conn);
+        //System.out.println("Return to pool: " + conn);
+    }
+
+    private HttpConnection
+    findConnection(CacheKey key,
+                   HashMap<CacheKey,LinkedList<HttpConnection>> pool) {
+        LinkedList<HttpConnection> l = pool.get(key);
+        if (l == null || l.size() == 0) {
+            return null;
+        } else {
+            HttpConnection c = l.removeFirst();
+            removeFromExpiryList(c);
+            return c;
+        }
+    }
+
+    /* called from cache cleaner only  */
+    private void
+    removeFromPool(HttpConnection c,
+                   HashMap<CacheKey,LinkedList<HttpConnection>> pool) {
+        //System.out.println("cacheCleaner removing: " + c);
+        LinkedList<HttpConnection> l = pool.get(c.cacheKey());
+        assert l != null;
+        boolean wasPresent = l.remove(c);
+        assert wasPresent;
+    }
+
+    private void
+    putConnection(HttpConnection c,
+                  HashMap<CacheKey,LinkedList<HttpConnection>> pool) {
+        CacheKey key = c.cacheKey();
+        LinkedList<HttpConnection> l = pool.get(key);
+        if (l == null) {
+            l = new LinkedList<>();
+            pool.put(key, l);
+        }
+        l.add(c);
+    }
+
+    // only runs while entries exist in cache
+
+    final class CacheCleaner extends Thread {
+
+        volatile boolean stopping;
+
+        CacheCleaner() {
+            super(null, null, "HTTP-Cache-cleaner", 0, false);
+            setDaemon(true);
+        }
+
+        synchronized boolean stopping() {
+            return stopping;
+        }
+
+        synchronized void stopCleaner() {
+            stopping = true;
+        }
+
+        @Override
+        public void run() {
+            while (!stopping()) {
+                try {
+                    Thread.sleep(3000);
+                } catch (InterruptedException e) {}
+                cleanCache();
+            }
+        }
+    }
+
+    synchronized void removeFromExpiryList(HttpConnection c) {
+        if (c == null) {
+            return;
+        }
+        ListIterator<ExpiryEntry> li = expiryList.listIterator();
+        while (li.hasNext()) {
+            ExpiryEntry e = li.next();
+            if (e.connection.equals(c)) {
+                li.remove();
+                return;
+            }
+        }
+        if (expiryList.isEmpty()) {
+            cleaner.stopCleaner();
+            cleaner = null;
+        }
+    }
+
+    private void cleanCache() {
+        long now = System.currentTimeMillis() / 1000;
+        LinkedList<HttpConnection> closelist = new LinkedList<>();
+
+        synchronized (this) {
+            ListIterator<ExpiryEntry> li = expiryList.listIterator();
+            while (li.hasNext()) {
+                ExpiryEntry entry = li.next();
+                if (entry.expiry <= now) {
+                    li.remove();
+                    HttpConnection c = entry.connection;
+                    closelist.add(c);
+                    if (c instanceof PlainHttpConnection) {
+                        removeFromPool(c, plainPool);
+                    } else {
+                        removeFromPool(c, sslPool);
+                    }
+                }
+            }
+        }
+        for (HttpConnection c : closelist) {
+            //System.out.println ("KAC: closing " + c);
+            c.close();
+        }
+    }
+
+    private synchronized void addToExpiryList(HttpConnection conn) {
+        long now = System.currentTimeMillis() / 1000;
+        long then = now + KEEP_ALIVE;
+
+        if (expiryList.isEmpty()) {
+            cleaner = new CacheCleaner();
+            cleaner.start();
+        }
+
+        ListIterator<ExpiryEntry> li = expiryList.listIterator();
+        while (li.hasNext()) {
+            ExpiryEntry entry = li.next();
+
+            if (then > entry.expiry) {
+                li.previous();
+                // insert here
+                li.add(new ExpiryEntry(conn, then));
+                return;
+            }
+        }
+        // first element of list
+        expiryList.add(new ExpiryEntry(conn, then));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/CookieFilter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.CookieManager;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import jdk.incubator.http.internal.common.Log;
+
+class CookieFilter implements HeaderFilter {
+
+    public CookieFilter() {
+    }
+
+    @Override
+    public void request(HttpRequestImpl r, MultiExchange<?,?> e) throws IOException {
+        HttpClientImpl client = e.client();
+        Optional<CookieManager> cookieManOpt = client.cookieManager();
+        if (cookieManOpt.isPresent()) {
+            CookieManager cookieMan = cookieManOpt.get();
+            Map<String,List<String>> userheaders = r.getUserHeaders().map();
+            Map<String,List<String>> cookies = cookieMan.get(r.uri(), userheaders);
+
+            // add the returned cookies
+            HttpHeadersImpl systemHeaders = r.getSystemHeaders();
+            if (cookies.isEmpty()) {
+                Log.logTrace("Request: no cookie to add for {0}",
+                             r.uri());
+            } else {
+                Log.logTrace("Request: adding cookies for {0}",
+                             r.uri());
+            }
+            for (String hdrname : cookies.keySet()) {
+                List<String> vals = cookies.get(hdrname);
+                for (String val : vals) {
+                    systemHeaders.addHeader(hdrname, val);
+                }
+            }
+        } else {
+            Log.logTrace("Request: No cookie manager found for {0}",
+                         r.uri());
+        }
+    }
+
+    @Override
+    public HttpRequestImpl response(Response r) throws IOException {
+        HttpHeaders hdrs = r.headers();
+        HttpRequestImpl request = r.request();
+        Exchange<?> e = r.exchange;
+        Log.logTrace("Response: processing cookies for {0}", request.uri());
+        Optional<CookieManager> cookieManOpt = e.client().cookieManager();
+        if (cookieManOpt.isPresent()) {
+            CookieManager cookieMan = cookieManOpt.get();
+            Log.logTrace("Response: parsing cookies from {0}", hdrs.map());
+            cookieMan.put(request.uri(), hdrs.map());
+        } else {
+            Log.logTrace("Response: No cookie manager found for {0}",
+                         request.uri());
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/DefaultPublisher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Flow;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Supplier;
+
+class DefaultPublisher<T> implements Flow.Publisher<T> {
+
+    private final Supplier<Optional<T>> supplier;
+    // this executor will be wrapped in another executor
+    // which may override it and just run in the calling thread
+    // if it knows the user call is blocking
+    private final Executor executor;
+
+    /**
+     * Supplier returns non empty Optionals until final
+     */
+    DefaultPublisher(Supplier<Optional<T>> supplier, Executor executor) {
+        this.supplier = supplier;
+        this.executor = executor;
+    }
+
+    @Override
+    public void subscribe(Flow.Subscriber<? super T> subscriber) {
+        try {
+            subscriber.onSubscribe(new Subscription(subscriber));
+        } catch (RejectedExecutionException e) {
+            subscriber.onError(new IllegalStateException(e));
+        }
+    }
+
+    private class Subscription implements Flow.Subscription {
+
+        private final Flow.Subscriber<? super T> subscriber;
+        private final AtomicBoolean done = new AtomicBoolean();
+
+        private final AtomicLong demand = new AtomicLong();
+
+        private final Lock consumerLock = new ReentrantLock();
+        private final Condition consumerAlarm = consumerLock.newCondition();
+
+        Subscription(Flow.Subscriber<? super T> subscriber) {
+            this.subscriber = subscriber;
+
+            executor.execute(() -> {
+                try {
+                    while (!done.get()) {
+                        consumerLock.lock();
+                        try {
+                            while (!done.get() && demand.get() == 0) {
+                                consumerAlarm.await();
+                            }
+                        } finally {
+                            consumerLock.unlock();
+                        }
+
+                        long nbItemsDemanded = demand.getAndSet(0);
+                        for (long i = 0; i < nbItemsDemanded && !done.get(); i++) {
+                            try {
+                                Optional<T> item = Objects.requireNonNull(supplier.get());
+                                item.ifPresentOrElse(subscriber::onNext, () -> {
+                                    if (done.compareAndSet(false, true)) {
+                                        subscriber.onComplete();
+                                    }
+                                });
+                            } catch (RuntimeException e) {
+                                if (done.compareAndSet(false, true)) {
+                                    subscriber.onError(e);
+                                }
+                            }
+                        }
+                    }
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    if (done.compareAndSet(false, true)) {
+                        subscriber.onError(e);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void request(long n) {
+            if (!done.get() && n > 0) {
+                demand.updateAndGet(d -> (d + n > 0) ? d + n : Long.MAX_VALUE);
+                wakeConsumer();
+            } else if (done.compareAndSet(false, true)) {
+                subscriber.onError(new IllegalArgumentException("request(" + n + ")"));
+            }
+        }
+
+        @Override
+        public void cancel() {
+            done.set(true);
+            wakeConsumer();
+        }
+
+        private void wakeConsumer() {
+            consumerLock.lock();
+            try {
+                consumerAlarm.signal();
+            } finally {
+                consumerLock.unlock();
+            }
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Exchange.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketPermission;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLPermission;
+import java.nio.ByteBuffer;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Utils;
+import jdk.incubator.http.internal.common.Log;
+
+/**
+ * One request/response exchange (handles 100/101 intermediate response also).
+ * depth field used to track number of times a new request is being sent
+ * for a given API request. If limit exceeded exception is thrown.
+ *
+ * Security check is performed here:
+ * - uses AccessControlContext captured at API level
+ * - checks for appropriate URLPermission for request
+ * - if permission allowed, grants equivalent SocketPermission to call
+ * - in case of direct HTTP proxy, checks additionally for access to proxy
+ *    (CONNECT proxying uses its own Exchange, so check done there)
+ *
+ */
+final class Exchange<T> {
+
+    final HttpRequestImpl request;
+    final HttpClientImpl client;
+    volatile ExchangeImpl<T> exchImpl;
+    final List<SocketPermission> permissions = new LinkedList<>();
+    final AccessControlContext acc;
+    final MultiExchange<?,T> multi;
+    final Executor parentExecutor;
+    final HttpRequest.BodyProcessor requestProcessor;
+    boolean upgrading; // to HTTP/2
+    volatile Executor responseExecutor;
+    final PushGroup<?,T> pushGroup;
+
+    // buffer for receiving response headers
+    private volatile ByteBuffer rxBuffer;
+
+    Exchange(HttpRequestImpl request, MultiExchange<?,T> multi) {
+        this.request = request;
+        this.upgrading = false;
+        this.client = multi.client();
+        this.multi = multi;
+        this.acc = multi.acc;
+        this.parentExecutor = multi.executor;
+        this.requestProcessor = request.requestProcessor;
+        this.pushGroup = multi.pushGroup;
+    }
+
+    /* If different AccessControlContext to be used  */
+    Exchange(HttpRequestImpl request,
+             MultiExchange<?,T> multi,
+             AccessControlContext acc)
+    {
+        this.request = request;
+        this.acc = acc;
+        this.upgrading = false;
+        this.client = multi.client();
+        this.multi = multi;
+        this.parentExecutor = multi.executor;
+        this.requestProcessor = request.requestProcessor;
+        this.pushGroup = multi.pushGroup;
+    }
+
+    PushGroup<?,T> getPushGroup() {
+        return pushGroup;
+    }
+
+    Executor executor() {
+        return parentExecutor;
+    }
+
+    public HttpRequestImpl request() {
+        return request;
+    }
+
+    HttpClientImpl client() {
+        return client;
+    }
+
+    ByteBuffer getBuffer() {
+        if(rxBuffer == null) {
+            synchronized (this) {
+                if(rxBuffer == null) {
+                    rxBuffer = Utils.getExchangeBuffer();
+                }
+            }
+        }
+        return rxBuffer;
+    }
+
+    public Response response() throws IOException, InterruptedException {
+        return responseImpl(null);
+    }
+
+    public T readBody(HttpResponse.BodyHandler<T> responseHandler) throws IOException {
+        return exchImpl.readBody(responseHandler, true);
+    }
+
+    public CompletableFuture<T> readBodyAsync(HttpResponse.BodyHandler<T> handler) {
+        return exchImpl.readBodyAsync(handler, true, responseExecutor);
+    }
+
+    public void cancel() {
+        if (exchImpl != null) {
+            exchImpl.cancel();
+        }
+    }
+
+    public void cancel(IOException cause) {
+        if (exchImpl != null) {
+            exchImpl.cancel(cause);
+        }
+    }
+
+    public void h2Upgrade() {
+        upgrading = true;
+        request.setH2Upgrade(client.client2());
+    }
+
+    static final SocketPermission[] SOCKET_ARRAY = new SocketPermission[0];
+
+    Response responseImpl(HttpConnection connection)
+        throws IOException, InterruptedException
+    {
+        SecurityException e = securityCheck(acc);
+        if (e != null) {
+            throw e;
+        }
+
+        if (permissions.size() > 0) {
+            try {
+                return AccessController.doPrivileged(
+                        (PrivilegedExceptionAction<Response>)() ->
+                             responseImpl0(connection),
+                        null,
+                        permissions.toArray(SOCKET_ARRAY));
+            } catch (Throwable ee) {
+                if (ee instanceof PrivilegedActionException) {
+                    ee = ee.getCause();
+                }
+                if (ee instanceof IOException) {
+                    throw (IOException) ee;
+                } else {
+                    throw new RuntimeException(ee); // TODO: fix
+                }
+            }
+        } else {
+            return responseImpl0(connection);
+        }
+    }
+
+    private Response responseImpl0(HttpConnection connection)
+        throws IOException, InterruptedException
+    {
+        exchImpl = ExchangeImpl.get(this, connection);
+        exchImpl.setClientForRequest(requestProcessor);
+        if (request.expectContinue()) {
+            Log.logTrace("Sending Expect: 100-Continue");
+            request.addSystemHeader("Expect", "100-Continue");
+            exchImpl.sendHeadersOnly();
+
+            Log.logTrace("Waiting for 407-Expectation-Failed or 100-Continue");
+            Response resp = exchImpl.getResponse();
+            HttpResponseImpl.logResponse(resp);
+            int rcode = resp.statusCode();
+            if (rcode != 100) {
+                Log.logTrace("Expectation failed: Received {0}",
+                             rcode);
+                if (upgrading && rcode == 101) {
+                    throw new IOException(
+                        "Unable to handle 101 while waiting for 100-Continue");
+                }
+                return resp;
+            }
+
+            Log.logTrace("Received 100-Continue: sending body");
+            exchImpl.sendBody();
+
+            Log.logTrace("Body sent: waiting for response");
+            resp = exchImpl.getResponse();
+            HttpResponseImpl.logResponse(resp);
+
+            return checkForUpgrade(resp, exchImpl);
+        } else {
+            exchImpl.sendRequest();
+            Response resp = exchImpl.getResponse();
+            HttpResponseImpl.logResponse(resp);
+            return checkForUpgrade(resp, exchImpl);
+        }
+    }
+
+    // Completed HttpResponse will be null if response succeeded
+    // will be a non null responseAsync if expect continue returns an error
+
+    public CompletableFuture<Response> responseAsync() {
+        // take one thread from supplied executor to handle response headers and body
+        responseExecutor = Utils.singleThreadExecutor(parentExecutor);
+        return responseAsyncImpl(null);
+    }
+
+    CompletableFuture<Response> responseAsyncImpl(HttpConnection connection) {
+        SecurityException e = securityCheck(acc);
+        if (e != null) {
+            return MinimalFuture.failedFuture(e);
+        }
+        if (permissions.size() > 0) {
+            return AccessController.doPrivileged(
+                    (PrivilegedAction<CompletableFuture<Response>>)() ->
+                        responseAsyncImpl0(connection),
+                    null,
+                    permissions.toArray(SOCKET_ARRAY));
+        } else {
+            return responseAsyncImpl0(connection);
+        }
+    }
+
+    CompletableFuture<Response> responseAsyncImpl0(HttpConnection connection) {
+        try {
+            exchImpl = ExchangeImpl.get(this, connection);
+        } catch (IOException | InterruptedException e) {
+            return MinimalFuture.failedFuture(e);
+        }
+        if (request.expectContinue()) {
+            request.addSystemHeader("Expect", "100-Continue");
+            Log.logTrace("Sending Expect: 100-Continue");
+            return exchImpl
+                    .sendHeadersAsync()
+                    .thenCompose((v) -> exchImpl.getResponseAsync(responseExecutor))
+                    .thenCompose((Response r1) -> {
+                        HttpResponseImpl.logResponse(r1);
+                        int rcode = r1.statusCode();
+                        if (rcode == 100) {
+                            Log.logTrace("Received 100-Continue: sending body");
+                            return exchImpl.sendBodyAsync(parentExecutor)
+                                .thenCompose((v) -> exchImpl.getResponseAsync(responseExecutor))
+                                .thenCompose((Response r2) -> {
+                                    return checkForUpgradeAsync(r2, exchImpl);
+                                }).thenApply((Response r) -> {
+                                    HttpResponseImpl.logResponse(r);
+                                    return r;
+                                });
+                        } else {
+                            Log.logTrace("Expectation failed: Received {0}",
+                                         rcode);
+                            if (upgrading && rcode == 101) {
+                                IOException failed = new IOException(
+                                        "Unable to handle 101 while waiting for 100");
+                                return MinimalFuture.failedFuture(failed);
+                            }
+                            return exchImpl.readBodyAsync(this::ignoreBody, false, responseExecutor)
+                                  .thenApply((v) -> {
+                                      return r1;
+                                  });
+                        }
+                    });
+        } else {
+            return exchImpl
+                .sendRequestAsync(parentExecutor)
+                .thenCompose((v) -> exchImpl.getResponseAsync(responseExecutor))
+                .thenCompose((Response r1) -> {
+                    return checkForUpgradeAsync(r1, exchImpl);
+                })
+                .thenApply((Response response) -> {
+                    HttpResponseImpl.logResponse(response);
+                    return response;
+                });
+        }
+    }
+
+    HttpResponse.BodyProcessor<T> ignoreBody(int status, HttpHeaders hdrs) {
+        return HttpResponse.BodyProcessor.discard((T)null);
+    }
+
+    // if this response was received in reply to an upgrade
+    // then create the Http2Connection from the HttpConnection
+    // initialize it and wait for the real response on a newly created Stream
+
+    private CompletableFuture<Response>
+    checkForUpgradeAsync(Response resp,
+                         ExchangeImpl<T> ex) {
+
+        int rcode = resp.statusCode();
+        if (upgrading && (rcode == 101)) {
+            Http1Exchange<T> e = (Http1Exchange<T>)ex;
+            // check for 101 switching protocols
+            // 101 responses are not supposed to contain a body.
+            //    => should we fail if there is one?
+            return e.readBodyAsync(this::ignoreBody, false, parentExecutor)
+                .thenCompose((T v) -> // v is null
+                     Http2Connection.createAsync(e.connection(),
+                                                 client.client2(),
+                                                 this, e.getBuffer())
+                        .thenCompose((Http2Connection c) -> {
+                            c.putConnection();
+                            Stream<T> s = c.getStream(1);
+                            exchImpl = s;
+                            return s.getResponseAsync(null);
+                        })
+                );
+        }
+        return MinimalFuture.completedFuture(resp);
+    }
+
+    private Response checkForUpgrade(Response resp,
+                                             ExchangeImpl<T> ex)
+        throws IOException, InterruptedException
+    {
+        int rcode = resp.statusCode();
+        if (upgrading && (rcode == 101)) {
+            Http1Exchange<T> e = (Http1Exchange<T>) ex;
+
+            // 101 responses are not supposed to contain a body.
+            //    => should we fail if there is one?
+            //    => readBody called here by analogy with
+            //       checkForUpgradeAsync above
+            e.readBody(this::ignoreBody, false);
+
+            // must get connection from Http1Exchange
+            Http2Connection h2con = new Http2Connection(e.connection(),
+                                                        client.client2(),
+                                                        this, e.getBuffer());
+            h2con.putConnection();
+            Stream<T> s = h2con.getStream(1);
+            exchImpl = s;
+            Response xx = s.getResponse();
+            HttpResponseImpl.logResponse(xx);
+            return xx;
+        }
+        return resp;
+    }
+
+    private URI getURIForSecurityCheck() {
+        URI u;
+        String method = request.method();
+        InetSocketAddress authority = request.authority();
+        URI uri = request.uri();
+
+        // CONNECT should be restricted at API level
+        if (method.equalsIgnoreCase("CONNECT")) {
+            try {
+                u = new URI("socket",
+                             null,
+                             authority.getHostString(),
+                             authority.getPort(),
+                             null,
+                             null,
+                             null);
+            } catch (URISyntaxException e) {
+                throw new InternalError(e); // shouldn't happen
+            }
+        } else {
+            u = uri;
+        }
+        return u;
+    }
+
+    /**
+     * Do the security check and return any exception.
+     * Return null if no check needed or passes.
+     *
+     * Also adds any generated permissions to the "permissions" list.
+     */
+    private SecurityException securityCheck(AccessControlContext acc) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            return null;
+        }
+
+        String method = request.method();
+        HttpHeaders userHeaders = request.getUserHeaders();
+        URI u = getURIForSecurityCheck();
+        URLPermission p = Utils.getPermission(u, method, userHeaders.map());
+
+        try {
+            assert acc != null;
+            sm.checkPermission(p, acc);
+            permissions.add(getSocketPermissionFor(u));
+        } catch (SecurityException e) {
+            return e;
+        }
+        ProxySelector ps = client.proxy().orElse(null);
+        if (ps != null) {
+            InetSocketAddress proxy = (InetSocketAddress)
+                    ps.select(u).get(0).address(); // TODO: check this
+            // may need additional check
+            if (!method.equals("CONNECT")) {
+                // a direct http proxy. Need to check access to proxy
+                try {
+                    u = new URI("socket", null, proxy.getHostString(),
+                        proxy.getPort(), null, null, null);
+                } catch (URISyntaxException e) {
+                    throw new InternalError(e); // shouldn't happen
+                }
+                p = new URLPermission(u.toString(), "CONNECT");
+                try {
+                    sm.checkPermission(p, acc);
+                } catch (SecurityException e) {
+                    permissions.clear();
+                    return e;
+                }
+                String sockperm = proxy.getHostString() +
+                        ":" + Integer.toString(proxy.getPort());
+
+                permissions.add(new SocketPermission(sockperm, "connect,resolve"));
+            }
+        }
+        return null;
+    }
+
+    HttpClient.Redirect followRedirects() {
+        return client.followRedirects();
+    }
+
+    HttpClient.Version version() {
+        return client.version();
+    }
+
+    private static SocketPermission getSocketPermissionFor(URI url) {
+        if (System.getSecurityManager() == null) {
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        String host = url.getHost();
+        sb.append(host);
+        int port = url.getPort();
+        if (port == -1) {
+            String scheme = url.getScheme();
+            if ("http".equals(scheme)) {
+                sb.append(":80");
+            } else { // scheme must be https
+                sb.append(":443");
+            }
+        } else {
+            sb.append(':')
+              .append(Integer.toString(port));
+        }
+        String target = sb.toString();
+        return new SocketPermission(target, "connect");
+    }
+
+    AccessControlContext getAccessControlContext() {
+        return acc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import jdk.incubator.http.RequestProcessors.ProcessorBase;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import static jdk.incubator.http.HttpClient.Version.HTTP_1_1;
+
+/**
+ * Splits request so that headers and body can be sent separately with optional
+ * (multiple) responses in between (e.g. 100 Continue). Also request and
+ * response always sent/received in different calls.
+ *
+ * Synchronous and asynchronous versions of each method are provided.
+ *
+ * Separate implementations of this class exist for HTTP/1.1 and HTTP/2
+ *      Http1Exchange   (HTTP/1.1)
+ *      Stream          (HTTP/2)
+ *
+ * These implementation classes are where work is allocated to threads.
+ */
+abstract class ExchangeImpl<T> {
+
+    final Exchange<T> exchange;
+
+    ExchangeImpl(Exchange<T> e) {
+        this.exchange = e;
+        if (e != null) {
+            // e == null means a http/2 pushed stream, therefore no request
+            setClientForRequest(e.requestProcessor);
+        }
+    }
+
+    final Exchange<T> getExchange() {
+        return exchange;
+    }
+
+
+    /**
+     * Returns the {@link HttpConnection} instance to which this exchange is
+     * assigned.
+     */
+    abstract HttpConnection connection();
+
+    /**
+     * Initiates a new exchange and assigns it to a connection if one exists
+     * already. connection usually null.
+     */
+    static <U> ExchangeImpl<U> get(Exchange<U> exchange, HttpConnection connection)
+        throws IOException, InterruptedException
+    {
+        HttpRequestImpl req = exchange.request();
+        if (exchange.version() == HTTP_1_1) {
+            return new Http1Exchange<>(exchange, connection);
+        } else {
+            Http2ClientImpl c2 = exchange.client().client2(); // TODO: improve
+            HttpRequestImpl request = exchange.request();
+            Http2Connection c = c2.getConnectionFor(request);
+            if (c == null) {
+                // no existing connection. Send request with HTTP 1 and then
+                // upgrade if successful
+                ExchangeImpl<U> ex = new Http1Exchange<>(exchange, connection);
+                exchange.h2Upgrade();
+                return ex;
+            }
+            return c.createStream(exchange);
+        }
+    }
+
+    /* The following methods have separate HTTP/1.1 and HTTP/2 implementations */
+
+    /**
+     * Sends the request headers only. May block until all sent.
+     */
+    abstract void sendHeadersOnly() throws IOException, InterruptedException;
+
+    // Blocking impl but in async style
+
+    CompletableFuture<Void> sendHeadersAsync() {
+        CompletableFuture<Void> cf = new MinimalFuture<>();
+        try {
+            sendHeadersOnly();
+            cf.complete(null);
+        } catch (Throwable t) {
+            cf.completeExceptionally(t);
+        }
+        // this is blocking. cf will already be completed.
+        return cf;
+    }
+
+    /**
+     * Gets response by blocking if necessary. This may be an
+     * intermediate response (like 101) or a final response 200 etc. Returns
+     * before body is read.
+     */
+    abstract Response getResponse() throws IOException;
+
+    abstract T readBody(HttpResponse.BodyHandler<T> handler, boolean returnToCache)
+            throws IOException;
+
+    abstract CompletableFuture<T> readBodyAsync(HttpResponse.BodyHandler<T> handler,
+                                                boolean returnToCache,
+                                                Executor executor);
+
+    // Builtin processors need access to HttpClientImpl
+    final void setClientForResponse(HttpResponse.BodyProcessor<T> proc) {
+        if (proc instanceof ResponseProcessors.AbstractProcessor) {
+            ResponseProcessors.AbstractProcessor<T> abProc =
+                    (ResponseProcessors.AbstractProcessor<T>)proc;
+            abProc.setClient(exchange.client());
+        }
+    }
+
+    final void setClientForRequest(HttpRequest.BodyProcessor proc) {
+        if (proc instanceof ProcessorBase) {
+            ProcessorBase abProc = (ProcessorBase)proc;
+            abProc.setClient(exchange.client());
+        }
+    }
+
+    /**
+     * Async version of getResponse. Completes before body is read.
+     */
+    abstract CompletableFuture<Response> getResponseAsync(Executor executor);
+
+    /**
+     * Sends a request body after request headers.
+     */
+    abstract void sendBody() throws IOException, InterruptedException;
+
+    // Async version of sendBody(). This only used when body sent separately
+    // to headers (100 continue)
+    CompletableFuture<Void> sendBodyAsync(Executor executor) {
+        CompletableFuture<Void> cf = new MinimalFuture<>();
+        executor.execute(() -> {
+            try {
+                sendBody();
+                cf.complete(null);
+            } catch (Throwable t) {
+                cf.completeExceptionally(t);
+            }
+        });
+        return cf;
+    }
+
+    /**
+     * Sends the entire request (headers and body) blocking.
+     */
+    void sendRequest() throws IOException, InterruptedException {
+        sendHeadersOnly();
+        sendBody();
+    }
+
+    CompletableFuture<Void> sendRequestAsync(Executor executor) {
+        CompletableFuture<Void> cf = new MinimalFuture<>();
+        executor.execute(() -> {
+            try {
+                sendRequest();
+                cf.complete(null);
+            } catch (Throwable t) {
+                cf.completeExceptionally(t);
+            }
+        });
+        return cf;
+    }
+    /**
+     * Cancels a request.  Not currently exposed through API.
+     */
+    abstract void cancel();
+
+    /**
+     * Cancels a request with a cause.  Not currently exposed through API.
+     */
+    abstract void cancel(IOException cause);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExecutorWrapper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.net.SocketPermission;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.Executor;
+import jdk.internal.misc.InnocuousThread;
+
+/**
+ * Wraps the supplied user Executor
+ *
+ * when a Security manager set, the correct access control context is used to execute task
+ *
+ * The access control context is captured at creation time of this object
+ */
+class ExecutorWrapper {
+
+    final Executor userExecutor; // the undeerlying executor provided by user
+    final Executor executor; // the executur which wraps the user's one
+    final AccessControlContext acc;
+    final ClassLoader ccl;
+
+    public ExecutorWrapper(Executor userExecutor, AccessControlContext acc) {
+        this.userExecutor = userExecutor;
+        this.acc = acc;
+        this.ccl = getCCL();
+        if (System.getSecurityManager() == null) {
+            this.executor = userExecutor;
+        } else {
+            this.executor = this::run;
+        }
+    }
+
+    private ClassLoader getCCL() {
+        return AccessController.doPrivileged(
+            (PrivilegedAction<ClassLoader>) () -> {
+                return Thread.currentThread().getContextClassLoader();
+            }
+        );
+    }
+
+    /**
+     * This is only used for the default HttpClient to deal with
+     * different application contexts that might be using it.
+     * The default client uses InnocuousThreads in its Executor.
+     */
+    private void prepareThread() {
+        final Thread me = Thread.currentThread();
+        if (!(me instanceof InnocuousThread))
+            return;
+        InnocuousThread innocuousMe = (InnocuousThread)me;
+
+        AccessController.doPrivileged(
+            (PrivilegedAction<Void>) () -> {
+                innocuousMe.setContextClassLoader(ccl);
+                innocuousMe.eraseThreadLocals();
+                return null;
+            }
+        );
+    }
+
+
+    void run(Runnable r) {
+        prepareThread();
+        try {
+            userExecutor.execute(r); // all throwables must be caught
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    public Executor userExecutor() {
+        return userExecutor;
+    }
+
+    public Executor executor() {
+        return executor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/FilterFactory.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.LinkedList;
+import java.util.List;
+
+class FilterFactory {
+
+    final LinkedList<Class<? extends HeaderFilter>> filterClasses = new LinkedList<>();
+
+    public void addFilter(Class<? extends HeaderFilter> type) {
+        filterClasses.add(type);
+    }
+
+    List<HeaderFilter> getFilterChain() {
+        List<HeaderFilter> l = new LinkedList<>();
+        for (Class<? extends HeaderFilter> clazz : filterClasses) {
+            try {
+                @SuppressWarnings("deprecation")
+                HeaderFilter headerFilter = clazz.newInstance();
+                l.add(headerFilter);
+            } catch (ReflectiveOperationException e) {
+                throw new InternalError(e);
+            }
+        }
+        return l;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HeaderFilter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+
+/**
+ * A header filter that can examine or modify, typically system headers for
+ * requests before they are sent, and responses before they are returned to the
+ * user. Some ability to resend requests is provided.
+ */
+interface HeaderFilter {
+
+    void request(HttpRequestImpl r, MultiExchange<?,?> e) throws IOException;
+
+    /**
+     * Returns null if response ok to be given to user.  Non null is a request
+     * that must be resent and its response given to user. If impl throws an
+     * exception that is returned to user instead.
+     */
+    HttpRequestImpl response(Response r) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HeaderParser.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+/* This is useful for the nightmare of parsing multi-part HTTP/RFC822 headers
+ * sensibly:
+ * From a String like: 'timeout=15, max=5'
+ * create an array of Strings:
+ * { {"timeout", "15"},
+ *   {"max", "5"}
+ * }
+ * From one like: 'Basic Realm="FuzzFace" Foo="Biz Bar Baz"'
+ * create one like (no quotes in literal):
+ * { {"basic", null},
+ *   {"realm", "FuzzFace"}
+ *   {"foo", "Biz Bar Baz"}
+ * }
+ * keys are converted to lower case, vals are left as is....
+ */
+class HeaderParser {
+
+    /* table of key/val pairs */
+    String raw;
+    String[][] tab;
+    int nkeys;
+    int asize = 10; // initial size of array is 10
+
+    public HeaderParser(String raw) {
+        this.raw = raw;
+        tab = new String[asize][2];
+        parse();
+    }
+
+    private HeaderParser () { }
+
+    /**
+     * Creates a new HeaderParser from this, whose keys (and corresponding
+     * values) range from "start" to "end-1"
+     */
+    public HeaderParser subsequence(int start, int end) {
+        if (start == 0 && end == nkeys) {
+            return this;
+        }
+        if (start < 0 || start >= end || end > nkeys) {
+            throw new IllegalArgumentException("invalid start or end");
+        }
+        HeaderParser n = new HeaderParser();
+        n.tab = new String [asize][2];
+        n.asize = asize;
+        System.arraycopy (tab, start, n.tab, 0, (end-start));
+        n.nkeys= (end-start);
+        return n;
+    }
+
+    private void parse() {
+
+        if (raw != null) {
+            raw = raw.trim();
+            char[] ca = raw.toCharArray();
+            int beg = 0, end = 0, i = 0;
+            boolean inKey = true;
+            boolean inQuote = false;
+            int len = ca.length;
+            while (end < len) {
+                char c = ca[end];
+                if ((c == '=') && !inQuote) { // end of a key
+                    tab[i][0] = new String(ca, beg, end-beg).toLowerCase(Locale.US);
+                    inKey = false;
+                    end++;
+                    beg = end;
+                } else if (c == '\"') {
+                    if (inQuote) {
+                        tab[i++][1]= new String(ca, beg, end-beg);
+                        inQuote=false;
+                        do {
+                            end++;
+                        } while (end < len && (ca[end] == ' ' || ca[end] == ','));
+                        inKey=true;
+                        beg=end;
+                    } else {
+                        inQuote=true;
+                        end++;
+                        beg=end;
+                    }
+                } else if (c == ' ' || c == ',') { // end key/val, of whatever we're in
+                    if (inQuote) {
+                        end++;
+                        continue;
+                    } else if (inKey) {
+                        tab[i++][0] = (new String(ca, beg, end-beg)).toLowerCase(Locale.US);
+                    } else {
+                        tab[i++][1] = (new String(ca, beg, end-beg));
+                    }
+                    while (end < len && (ca[end] == ' ' || ca[end] == ',')) {
+                        end++;
+                    }
+                    inKey = true;
+                    beg = end;
+                } else {
+                    end++;
+                }
+                if (i == asize) {
+                    asize = asize * 2;
+                    String[][] ntab = new String[asize][2];
+                    System.arraycopy (tab, 0, ntab, 0, tab.length);
+                    tab = ntab;
+                }
+            }
+            // get last key/val, if any
+            if (--end > beg) {
+                if (!inKey) {
+                    if (ca[end] == '\"') {
+                        tab[i++][1] = (new String(ca, beg, end-beg));
+                    } else {
+                        tab[i++][1] = (new String(ca, beg, end-beg+1));
+                    }
+                } else {
+                    tab[i++][0] = (new String(ca, beg, end-beg+1)).toLowerCase();
+                }
+            } else if (end == beg) {
+                if (!inKey) {
+                    if (ca[end] == '\"') {
+                        tab[i++][1] = String.valueOf(ca[end-1]);
+                    } else {
+                        tab[i++][1] = String.valueOf(ca[end]);
+                    }
+                } else {
+                    tab[i++][0] = String.valueOf(ca[end]).toLowerCase();
+                }
+            }
+            nkeys=i;
+        }
+    }
+
+    public String findKey(int i) {
+        if (i < 0 || i > asize) {
+            return null;
+        }
+        return tab[i][0];
+    }
+
+    public String findValue(int i) {
+        if (i < 0 || i > asize) {
+            return null;
+        }
+        return tab[i][1];
+    }
+
+    public String findValue(String key) {
+        return findValue(key, null);
+    }
+
+    public String findValue(String k, String Default) {
+        if (k == null) {
+            return Default;
+        }
+        k = k.toLowerCase(Locale.US);
+        for (int i = 0; i < asize; ++i) {
+            if (tab[i][0] == null) {
+                return Default;
+            } else if (k.equals(tab[i][0])) {
+                return tab[i][1];
+            }
+        }
+        return Default;
+    }
+
+    class ParserIterator implements Iterator<String> {
+        int index;
+        boolean returnsValue; // or key
+
+        ParserIterator (boolean returnValue) {
+            returnsValue = returnValue;
+        }
+        @Override
+        public boolean hasNext () {
+            return index<nkeys;
+        }
+        @Override
+        public String next () {
+            if (index >= nkeys) {
+                throw new NoSuchElementException();
+            }
+            return tab[index++][returnsValue?1:0];
+        }
+    }
+
+    public Iterator<String> keys () {
+        return new ParserIterator (false);
+    }
+
+    public Iterator<String> values () {
+        return new ParserIterator (true);
+    }
+
+    @Override
+    public String toString () {
+        Iterator<String> k = keys();
+        StringBuilder sb = new StringBuilder();
+        sb.append("{size=").append(asize).append(" nkeys=").append(nkeys)
+                .append(' ');
+        for (int i=0; k.hasNext(); i++) {
+            String key = k.next();
+            String val = findValue (i);
+            if (val != null && "".equals (val)) {
+                val = null;
+            }
+            sb.append(" {").append(key).append(val == null ? "" : "," + val)
+                    .append('}');
+            if (k.hasNext()) {
+                sb.append (',');
+            }
+        }
+        sb.append (" }");
+        return sb.toString();
+    }
+
+    public int findInt(String k, int Default) {
+        try {
+            return Integer.parseInt(findValue(k, String.valueOf(Default)));
+        } catch (Throwable t) {
+            return Default;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1Exchange.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import jdk.incubator.http.HttpResponse.BodyHandler;
+import jdk.incubator.http.HttpResponse.BodyProcessor;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.Executor;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * Encapsulates one HTTP/1.1 request/responseAsync exchange.
+ */
+class Http1Exchange<T> extends ExchangeImpl<T> {
+
+    final HttpRequestImpl request;        // main request
+    final List<CompletableFuture<?>> operations; // used for cancel
+    final Http1Request requestAction;
+    volatile Http1Response<T> response;
+    final HttpConnection connection;
+    final HttpClientImpl client;
+    final Executor executor;
+    final ByteBuffer buffer; // used for receiving
+
+    @Override
+    public String toString() {
+        return request.toString();
+    }
+
+    HttpRequestImpl request() {
+        return request;
+    }
+
+    Http1Exchange(Exchange<T> exchange, HttpConnection connection)
+        throws IOException
+    {
+        super(exchange);
+        this.request = exchange.request();
+        this.client = exchange.client();
+        this.executor = exchange.executor();
+        this.operations = Collections.synchronizedList(new LinkedList<>());
+        this.buffer = exchange.getBuffer();
+        if (connection != null) {
+            this.connection = connection;
+        } else {
+            InetSocketAddress addr = request.getAddress(client);
+            this.connection = HttpConnection.getConnection(addr, client, request);
+        }
+        this.requestAction = new Http1Request(request, client, this.connection);
+    }
+
+
+    HttpConnection connection() {
+        return connection;
+    }
+
+
+    @Override
+    T readBody(BodyHandler<T> handler, boolean returnToCache)
+        throws IOException
+    {
+        BodyProcessor<T> processor = handler.apply(response.responseCode(),
+                                                   response.responseHeaders());
+        setClientForResponse(processor);
+        CompletableFuture<T> bodyCF = response.readBody(processor,
+                                                        returnToCache,
+                                                        this::executeInline);
+        try {
+            return bodyCF.join();
+        } catch (CompletionException e) {
+            throw Utils.getIOException(e);
+        }
+    }
+
+    private void executeInline(Runnable r) {
+        r.run();
+    }
+
+    synchronized ByteBuffer getBuffer() {
+        return buffer;
+    }
+
+    @Override
+    CompletableFuture<T> readBodyAsync(BodyHandler<T> handler,
+                                       boolean returnToCache,
+                                       Executor executor)
+    {
+        BodyProcessor<T> processor = handler.apply(response.responseCode(),
+                                                   response.responseHeaders());
+        setClientForResponse(processor);
+        CompletableFuture<T> bodyCF = response.readBody(processor,
+                                                        returnToCache,
+                                                        executor);
+        return bodyCF;
+    }
+
+    @Override
+    void sendHeadersOnly() throws IOException, InterruptedException {
+        try {
+            if (!connection.connected()) {
+                connection.connect();
+            }
+            requestAction.sendHeadersOnly();
+        } catch (Throwable e) {
+            connection.close();
+            throw e;
+        }
+    }
+
+    @Override
+    void sendBody() throws IOException {
+        try {
+            requestAction.continueRequest();
+        } catch (Throwable e) {
+            connection.close();
+            throw e;
+        }
+    }
+
+    @Override
+    Response getResponse() throws IOException {
+        try {
+            response = new Http1Response<>(connection, this);
+            response.readHeaders();
+            return response.response();
+        } catch (Throwable t) {
+            connection.close();
+            throw t;
+        }
+    }
+
+    private void closeConnection() {
+        connection.close();
+    }
+
+    /**
+     * Cancel checks to see if request and responseAsync finished already.
+     * If not it closes the connection and completes all pending operations
+     */
+    @Override
+    void cancel() {
+        cancel(new IOException("Request cancelled"));
+    }
+
+    /**
+     * Cancel checks to see if request and responseAsync finished already.
+     * If not it closes the connection and completes all pending operations
+     */
+    @Override
+    synchronized void cancel(IOException cause) {
+        if (requestAction != null && requestAction.finished()
+                && response != null && response.finished()) {
+            return;
+        }
+        connection.close();
+        int count = 0;
+        for (CompletableFuture<?> cf : operations) {
+            cf.completeExceptionally(cause);
+            count++;
+        }
+        Log.logError("Http1Exchange.cancel: count=" + count);
+    }
+
+    CompletableFuture<Response> getResponseAsyncImpl(Executor executor) {
+        CompletableFuture<Response> cf = new MinimalFuture<>();
+        executor.execute(() -> {
+            try {
+                response = new Http1Response<>(connection, Http1Exchange.this);
+                response.readHeaders();
+                cf.complete(response.response());
+            } catch (Throwable e) {
+                cf.completeExceptionally(e);
+            }
+        });
+        return cf;
+    }
+
+    @Override
+    CompletableFuture<Response> getResponseAsync(Executor executor) {
+        CompletableFuture<Response> cf =
+            connection.whenReceivingResponse()
+                      .thenCompose((v) -> getResponseAsyncImpl(executor));
+
+        operations.add(cf);
+        return cf;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1Request.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.net.InetSocketAddress;
+import jdk.incubator.http.HttpConnection.Mode;
+import jdk.incubator.http.RequestProcessors.ProcessorBase;
+import java.nio.charset.StandardCharsets;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.Flow;
+
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ *  A HTTP/1.1 request.
+ *
+ * send() -> Writes the request + body to the given channel, in one blocking
+ * operation.
+ */
+class Http1Request {
+    final HttpClientImpl client;
+    final HttpRequestImpl request;
+    final HttpConnection chan;
+    // Multiple buffers are used to hold different parts of request
+    // See line 206 and below for description
+    final ByteBuffer[] buffers;
+    final HttpRequest.BodyProcessor requestProc;
+    final HttpHeaders userHeaders;
+    final HttpHeadersImpl systemHeaders;
+    boolean streaming;
+    long contentLength;
+    final CompletableFuture<Void> cf;
+
+    Http1Request(HttpRequestImpl request, HttpClientImpl client, HttpConnection connection)
+        throws IOException
+    {
+        this.client = client;
+        this.request = request;
+        this.chan = connection;
+        buffers = new ByteBuffer[5]; // TODO: check
+        this.requestProc = request.requestProcessor;
+        this.userHeaders = request.getUserHeaders();
+        this.systemHeaders = request.getSystemHeaders();
+        this.cf = new MinimalFuture<>();
+    }
+
+    private void logHeaders() throws IOException {
+        StringBuilder sb = new StringBuilder(256);
+        sb.append("REQUEST HEADERS:\n");
+        Log.dumpHeaders(sb, "    ", systemHeaders);
+        Log.dumpHeaders(sb, "    ", userHeaders);
+        Log.logHeaders(sb.toString());
+    }
+
+    private void dummy(long x) {
+        // not used in this class
+    }
+
+    private void collectHeaders0() throws IOException {
+        if (Log.headers()) {
+            logHeaders();
+        }
+        StringBuilder sb = new StringBuilder(256);
+        collectHeaders1(sb, request, systemHeaders);
+        collectHeaders1(sb, request, userHeaders);
+        sb.append("\r\n");
+        String headers = sb.toString();
+        buffers[1] = ByteBuffer.wrap(headers.getBytes(StandardCharsets.US_ASCII));
+    }
+
+    private void collectHeaders1(StringBuilder sb,
+                                 HttpRequestImpl request,
+                                 HttpHeaders headers)
+        throws IOException
+    {
+        Map<String,List<String>> h = headers.map();
+        Set<Map.Entry<String,List<String>>> entries = h.entrySet();
+
+        for (Map.Entry<String,List<String>> entry : entries) {
+            String key = entry.getKey();
+            List<String> values = entry.getValue();
+            for (String value : values) {
+                sb.append(key)
+                  .append(": ")
+                  .append(value)
+                  .append("\r\n");
+            }
+        }
+    }
+
+    private String getPathAndQuery(URI uri) {
+        String path = uri.getPath();
+        String query = uri.getQuery();
+        if (path == null || path.equals("")) {
+            path = "/";
+        }
+        if (query == null) {
+            query = "";
+        }
+        if (query.equals("")) {
+            return path;
+        } else {
+            return path + "?" + query;
+        }
+    }
+
+    private String authorityString(InetSocketAddress addr) {
+        return addr.getHostString() + ":" + addr.getPort();
+    }
+
+    private String hostString() {
+        URI uri = request.uri();
+        int port = uri.getPort();
+        String host = uri.getHost();
+
+        boolean defaultPort;
+        if (port == -1) {
+            defaultPort = true;
+        } else if (request.secure()) {
+            defaultPort = port == 443;
+        } else {
+            defaultPort = port == 80;
+        }
+
+        if (defaultPort) {
+            return host;
+        } else {
+            return host + ":" + Integer.toString(port);
+        }
+    }
+
+    private String requestURI() {
+        URI uri = request.uri();
+        String method = request.method();
+
+        if ((request.proxy(client) == null && !method.equals("CONNECT"))
+                || request.isWebSocket()) {
+            return getPathAndQuery(uri);
+        }
+        if (request.secure()) {
+            if (request.method().equals("CONNECT")) {
+                // use authority for connect itself
+                return authorityString(request.authority());
+            } else {
+                // requests over tunnel do not require full URL
+                return getPathAndQuery(uri);
+            }
+        }
+        return uri == null? authorityString(request.authority()) : uri.toString();
+    }
+
+    void sendHeadersOnly() throws IOException {
+        collectHeaders();
+        chan.write(buffers, 0, 2);
+    }
+
+    void sendRequest() throws IOException {
+        collectHeaders();
+        chan.configureMode(Mode.BLOCKING);
+        if (contentLength == 0) {
+            chan.write(buffers, 0, 2);
+        } else if (contentLength > 0) {
+            writeFixedContent(true);
+        } else {
+            writeStreamedContent(true);
+        }
+        setFinished();
+    }
+
+    private boolean finished;
+
+    synchronized boolean finished() {
+        return  finished;
+    }
+
+    synchronized void setFinished() {
+        finished = true;
+    }
+
+    private void collectHeaders() throws IOException {
+        if (Log.requests() && request != null) {
+            Log.logRequest(request.toString());
+        }
+        String uriString = requestURI();
+        StringBuilder sb = new StringBuilder(64);
+        sb.append(request.method())
+          .append(' ')
+          .append(uriString)
+          .append(" HTTP/1.1\r\n");
+        String cmd = sb.toString();
+
+        buffers[0] = ByteBuffer.wrap(cmd.getBytes(StandardCharsets.US_ASCII));
+        URI uri = request.uri();
+        if (uri != null) {
+            systemHeaders.setHeader("Host", hostString());
+        }
+        if (request == null) {
+            // this is not a user request. No content
+            contentLength = 0;
+        } else {
+            contentLength = requestProc.contentLength();
+        }
+
+        if (contentLength == 0) {
+            systemHeaders.setHeader("Content-Length", "0");
+            collectHeaders0();
+        } else if (contentLength > 0) {
+            /* [0] request line [1] headers [2] body  */
+            systemHeaders.setHeader("Content-Length",
+                                    Integer.toString((int) contentLength));
+            streaming = false;
+            collectHeaders0();
+            buffers[2] = getBuffer();
+        } else {
+            /* Chunked:
+             *
+             * [0] request line [1] headers [2] chunk header [3] chunk data [4]
+             * final chunk header and trailing CRLF of previous chunks
+             *
+             * 2,3,4 used repeatedly */
+            streaming = true;
+            systemHeaders.setHeader("Transfer-encoding", "chunked");
+            collectHeaders0();
+            buffers[3] = getBuffer();
+        }
+    }
+
+    private ByteBuffer getBuffer() {
+        return ByteBuffer.allocate(Utils.BUFSIZE);
+    }
+
+    // The following two methods used by Http1Exchange to handle expect continue
+
+    void continueRequest() throws IOException {
+        if (streaming) {
+            writeStreamedContent(false);
+        } else {
+            writeFixedContent(false);
+        }
+        setFinished();
+    }
+
+    class StreamSubscriber extends ProcessorBase
+        implements Flow.Subscriber<ByteBuffer>
+    {
+        volatile Flow.Subscription subscription;
+        volatile boolean includeHeaders;
+
+        StreamSubscriber(boolean includeHeaders) {
+            this.includeHeaders = includeHeaders;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            if (this.subscription != null) {
+                throw new IllegalStateException("already subscribed");
+            }
+            this.subscription = subscription;
+            subscription.request(1);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            int startbuf, nbufs;
+
+            if (cf.isDone()) {
+                throw new IllegalStateException("subscription already completed");
+            }
+
+            if (includeHeaders) {
+                startbuf = 0;
+                nbufs = 5;
+            } else {
+                startbuf = 2;
+                nbufs = 3;
+            }
+            int chunklen = item.remaining();
+            buffers[3] = item;
+            buffers[2] = getHeader(chunklen);
+            buffers[4] = CRLF_BUFFER();
+            try {
+                chan.write(buffers, startbuf, nbufs);
+            } catch (IOException e) {
+                subscription.cancel();
+                cf.completeExceptionally(e);
+            }
+            includeHeaders = false;
+            subscription.request(1);
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            if (cf.isDone()) {
+                return;
+            }
+            subscription.cancel();
+            cf.completeExceptionally(throwable);
+        }
+
+        @Override
+        public void onComplete() {
+            if (cf.isDone()) {
+                throw new IllegalStateException("subscription already completed");
+            }
+            buffers[3] = EMPTY_CHUNK_HEADER();
+            buffers[4] = CRLF_BUFFER();
+            try {
+                chan.write(buffers, 3, 2);
+            } catch (IOException ex) {
+                cf.completeExceptionally(ex);
+                return;
+            }
+            cf.complete(null);
+        }
+    }
+
+    private void waitForCompletion() throws IOException {
+        try {
+            cf.join();
+        } catch (CompletionException e) {
+            throw Utils.getIOException(e);
+        }
+    }
+
+    /* Entire request is sent, or just body only  */
+    private void writeStreamedContent(boolean includeHeaders)
+        throws IOException
+    {
+        StreamSubscriber subscriber = new StreamSubscriber(includeHeaders);
+        subscriber.setClient(client);
+        requestProc.subscribe(subscriber);
+        waitForCompletion();
+    }
+
+    class FixedContentSubscriber extends ProcessorBase
+        implements Flow.Subscriber<ByteBuffer>
+    {
+        volatile Flow.Subscription subscription;
+        volatile boolean includeHeaders;
+        volatile long contentWritten = 0;
+
+        FixedContentSubscriber(boolean includeHeaders) {
+            this.includeHeaders = includeHeaders;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            if (this.subscription != null) {
+                throw new IllegalStateException("already subscribed");
+            }
+            this.subscription = subscription;
+            subscription.request(1);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            int startbuf, nbufs;
+            long headersLength;
+
+            if (includeHeaders) {
+                startbuf = 0;
+                nbufs = 3;
+                headersLength = buffers[0].remaining() + buffers[1].remaining();
+            } else {
+                startbuf = 2;
+                nbufs = 1;
+                headersLength = 0;
+            }
+            buffers[2] = item;
+            try {
+                long writing = buffers[2].remaining() + headersLength;
+                contentWritten += buffers[2].remaining();
+                chan.checkWrite(writing, buffers, startbuf, nbufs);
+
+                if (contentWritten > contentLength) {
+                    String msg = "Too many bytes in request body. Expected: " +
+                        Long.toString(contentLength) + " Sent: " +
+                        Long.toString(contentWritten);
+                    throw new IOException(msg);
+                }
+                subscription.request(1);
+            } catch (IOException e) {
+                subscription.cancel();
+                cf.completeExceptionally(e);
+            }
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            if (cf.isDone()) {
+                return;
+            }
+            subscription.cancel();
+            cf.completeExceptionally(throwable);
+        }
+
+        @Override
+        public void onComplete() {
+            if (cf.isDone()) {
+                throw new IllegalStateException("subscription already completed");
+            }
+
+            if (contentLength > contentWritten) {
+                subscription.cancel();
+                Exception e = new IOException("Too few bytes returned by the processor");
+                cf.completeExceptionally(e);
+            } else {
+                cf.complete(null);
+            }
+        }
+    }
+
+    /* Entire request is sent, or just body only */
+    private void writeFixedContent(boolean includeHeaders)
+            throws IOException {
+        if (contentLength == 0) {
+            return;
+        }
+        FixedContentSubscriber subscriber = new FixedContentSubscriber(includeHeaders);
+        subscriber.setClient(client);
+        requestProc.subscribe(subscriber);
+        waitForCompletion();
+    }
+
+    private static final byte[] CRLF = {'\r', '\n'};
+    private static final byte[] EMPTY_CHUNK_BYTES = {'0', '\r', '\n'};
+
+    private ByteBuffer CRLF_BUFFER() {
+        return ByteBuffer.wrap(CRLF);
+    }
+
+    private ByteBuffer EMPTY_CHUNK_HEADER() {
+        return ByteBuffer.wrap(EMPTY_CHUNK_BYTES);
+    }
+
+    /* Returns a header for a particular chunk size */
+    private static ByteBuffer getHeader(int size){
+        String hexStr =  Integer.toHexString(size);
+        byte[] hexBytes = hexStr.getBytes(US_ASCII);
+        byte[] header = new byte[hexStr.length()+2];
+        System.arraycopy(hexBytes, 0, header, 0, hexBytes.length);
+        header[hexBytes.length] = CRLF[0];
+        header[hexBytes.length+1] = CRLF[1];
+        return ByteBuffer.wrap(header);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1Response.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import jdk.incubator.http.internal.common.Log;
+import static jdk.incubator.http.HttpClient.Version.HTTP_1_1;
+
+/**
+ * Handles a HTTP/1.1 response in two blocking calls. readHeaders() and
+ * readBody(). There can be more than one of these per Http exchange.
+ */
+class Http1Response<T> {
+
+    private volatile ResponseContent content;
+    private final HttpRequestImpl request;
+    private Response response;
+    private final HttpConnection connection;
+    private ResponseHeaders headers;
+    private int responseCode;
+    private final ByteBuffer buffer; // same buffer used for reading status line and headers
+    private final Http1Exchange<T> exchange;
+    private final boolean redirecting; // redirecting
+    private boolean return2Cache; // return connection to cache when finished
+
+    Http1Response(HttpConnection conn, Http1Exchange<T> exchange) {
+        this.request = exchange.request();
+        this.exchange = exchange;
+        this.connection = conn;
+        this.redirecting = false;
+        buffer = exchange.getBuffer();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void readHeaders() throws IOException {
+        String statusline = readStatusLine();
+        if (statusline == null) {
+            if (Log.errors()) {
+                Log.logError("Connection closed. Retry");
+            }
+            connection.close();
+            // connection was closed
+            throw new IOException("Connection closed");
+        }
+        if (!statusline.startsWith("HTTP/1.")) {
+            throw new IOException("Invalid status line: " + statusline);
+        }
+        if (Log.trace()) {
+            Log.logTrace("Statusline: {0}", statusline);
+        }
+        char c = statusline.charAt(7);
+        responseCode = Integer.parseInt(statusline.substring(9, 12));
+
+        headers = new ResponseHeaders(connection, buffer);
+        if (Log.headers()) {
+            logHeaders(headers);
+        }
+        response = new Response(
+                request, exchange.getExchange(),
+                headers, responseCode, HTTP_1_1);
+    }
+
+    private boolean finished;
+
+    synchronized void completed() {
+        finished = true;
+    }
+
+    synchronized boolean finished() {
+        return finished;
+    }
+
+    int fixupContentLen(int clen) {
+        if (request.method().equalsIgnoreCase("HEAD")) {
+            return 0;
+        }
+        if (clen == -1) {
+            if (headers.firstValue("Transfer-encoding").orElse("")
+                       .equalsIgnoreCase("chunked")) {
+                return -1;
+            }
+            return 0;
+        }
+        return clen;
+    }
+
+    public CompletableFuture<T> readBody(
+            HttpResponse.BodyProcessor<T> p,
+            boolean return2Cache,
+            Executor executor) {
+        final BlockingPushPublisher<ByteBuffer> publisher = new BlockingPushPublisher<>();
+        return readBody(p, return2Cache, publisher, executor);
+    }
+
+    private CompletableFuture<T> readBody(
+            HttpResponse.BodyProcessor<T> p,
+            boolean return2Cache,
+            AbstractPushPublisher<ByteBuffer> publisher,
+            Executor executor) {
+        this.return2Cache = return2Cache;
+        final jdk.incubator.http.HttpResponse.BodyProcessor<T> pusher = p;
+        final CompletableFuture<T> cf = p.getBody().toCompletableFuture();
+
+        int clen0;
+        try {
+            clen0 = headers.getContentLength();
+        } catch (IOException ex) {
+            cf.completeExceptionally(ex);
+            return cf;
+        }
+        final int clen = fixupContentLen(clen0);
+
+        executor.execute(() -> {
+            try {
+                content = new ResponseContent(
+                        connection, clen, headers, pusher,
+                        publisher.asDataConsumer(),
+                        (t -> {
+                            publisher.acceptError(t);
+                            connection.close();
+                            cf.completeExceptionally(t);
+                        }),
+                        () -> onFinished()
+                );
+                publisher.subscribe(p);
+                if (cf.isCompletedExceptionally()) {
+                    // if an error occurs during subscription
+                    connection.close();
+                    return;
+                }
+                content.pushBody(buffer);
+            } catch (Throwable t) {
+                cf.completeExceptionally(t);
+            }
+        });
+        return cf;
+    }
+
+    private void onFinished() {
+        if (return2Cache) {
+            connection.returnToCache(headers);
+        }
+    }
+
+    private void logHeaders(ResponseHeaders headers) {
+        StringBuilder sb = new StringBuilder("RESPONSE HEADERS:\n");
+        Log.dumpHeaders(sb, "    ", headers);
+        Log.logHeaders(sb.toString());
+    }
+
+    Response response() {
+        return response;
+    }
+
+    boolean redirecting() {
+        return redirecting;
+    }
+
+    HttpHeaders responseHeaders() {
+        return headers;
+    }
+
+    int responseCode() {
+        return responseCode;
+    }
+
+    static final char CR = '\r';
+    static final char LF = '\n';
+
+    private int getBuffer() throws IOException {
+        int n = buffer.remaining();
+
+        if (n == 0) {
+            buffer.clear();
+            return connection.read(buffer);
+        }
+        return n;
+    }
+
+    String readStatusLine() throws IOException {
+        boolean cr = false;
+        StringBuilder statusLine = new StringBuilder(128);
+        ByteBuffer b = buffer;
+        while (getBuffer() != -1) {
+            byte[] buf = b.array();
+            int offset = b.position();
+            int len = b.limit() - offset;
+
+            for (int i = 0; i < len; i++) {
+                char c = (char) buf[i+offset];
+
+                if (cr) {
+                    if (c == LF) {
+                        b.position(i + 1 + offset);
+                        return statusLine.toString();
+                    } else {
+                        throw new IOException("invalid status line");
+                    }
+                }
+                if (c == CR) {
+                    cr = true;
+                } else {
+                    statusLine.append(c);
+                }
+            }
+            // unlikely, but possible, that multiple reads required
+            b.position(b.limit());
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2ClientImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import jdk.incubator.http.internal.common.Utils;
+import jdk.incubator.http.internal.frame.SettingsFrame;
+import static jdk.incubator.http.internal.frame.SettingsFrame.INITIAL_WINDOW_SIZE;
+import static jdk.incubator.http.internal.frame.SettingsFrame.ENABLE_PUSH;
+import static jdk.incubator.http.internal.frame.SettingsFrame.HEADER_TABLE_SIZE;
+import static jdk.incubator.http.internal.frame.SettingsFrame.MAX_CONCURRENT_STREAMS;
+import static jdk.incubator.http.internal.frame.SettingsFrame.MAX_FRAME_SIZE;
+
+/**
+ *  Http2 specific aspects of HttpClientImpl
+ */
+class Http2ClientImpl {
+
+    private final HttpClientImpl client;
+
+    Http2ClientImpl(HttpClientImpl client) {
+        this.client = client;
+    }
+
+    /* Map key is "scheme:host:port" */
+    private final Map<String,Http2Connection> connections = new ConcurrentHashMap<>();
+
+    private final Set<String> opening = Collections.synchronizedSet(new HashSet<>());
+
+    boolean haveConnectionFor(URI uri, InetSocketAddress proxy) {
+        return connections.containsKey(Http2Connection.keyFor(uri,proxy));
+    }
+
+    /**
+     * If a https request then blocks and waits until a connection is opened.
+     * Returns null if the request is 'http' as a different (upgrade)
+     * mechanism is used.
+     *
+     * Only one connection per destination is created. Blocks when opening
+     * connection, or when waiting for connection to be opened.
+     * First thread opens the connection and notifies the others when done.
+     *
+     * If the request is secure (https) then we open the connection here.
+     * If not, then the more complicated upgrade from 1.1 to 2 happens (not here)
+     * In latter case, when the Http2Connection is connected, putConnection() must
+     * be called to store it.
+     */
+    Http2Connection getConnectionFor(HttpRequestImpl req)
+            throws IOException, InterruptedException {
+        URI uri = req.uri();
+        InetSocketAddress proxy = req.proxy(client);
+        String key = Http2Connection.keyFor(uri, proxy);
+        Http2Connection connection = connections.get(key);
+        if (connection != null) { // fast path if connection already exists
+            return connection;
+        }
+        synchronized (opening) {
+            while ((connection = connections.get(key)) == null) {
+                if (!req.secure()) {
+                    return null;
+                }
+                if (!opening.contains(key)) {
+                    opening.add(key);
+                    break;
+                } else {
+                    opening.wait();
+                }
+            }
+        }
+        if (connection != null) {
+            return connection;
+        }
+        // we are opening the connection here blocking until it is done.
+        connection = new Http2Connection(req, this);
+        synchronized (opening) {
+            connections.put(key, connection);
+            opening.remove(key);
+            opening.notifyAll();
+        }
+        return connection;
+    }
+
+
+    /*
+     * TODO: If there isn't a connection to the same destination, then
+     * store it. If there is already a connection, then close it
+     */
+    void putConnection(Http2Connection c) {
+        connections.put(c.key(), c);
+    }
+
+    void deleteConnection(Http2Connection c) {
+        connections.remove(c.key());
+    }
+
+    HttpClientImpl client() {
+        return client;
+    }
+
+    /** Returns the client settings as a base64 (url) encoded string */
+    String getSettingsString() {
+        SettingsFrame sf = getClientSettings();
+        byte[] settings = sf.toByteArray(); // without the header
+        Base64.Encoder encoder = Base64.getUrlEncoder()
+                                       .withoutPadding();
+        return encoder.encodeToString(settings);
+    }
+
+    private static final int K = 1024;
+
+    SettingsFrame getClientSettings() {
+        SettingsFrame frame = new SettingsFrame();
+        frame.setParameter(HEADER_TABLE_SIZE, Utils.getIntegerNetProperty(
+                "jdk.httpclient.hpack.maxheadertablesize", 16 * K));
+        frame.setParameter(ENABLE_PUSH, Utils.getIntegerNetProperty(
+            "jdk.httpclient.enablepush", 1));
+        frame.setParameter(MAX_CONCURRENT_STREAMS, Utils.getIntegerNetProperty(
+            "jdk.httpclient.maxstreams", 16));
+        frame.setParameter(INITIAL_WINDOW_SIZE, Utils.getIntegerNetProperty(
+            "jdk.httpclient.windowsize", 64 * K - 1));
+        frame.setParameter(MAX_FRAME_SIZE, Utils.getIntegerNetProperty(
+            "jdk.httpclient.maxframesize", 16 * K));
+        return frame;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import jdk.incubator.http.HttpConnection.Mode;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+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.ArrayList;
+import java.util.Collections;
+import java.util.Formatter;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
+import jdk.incubator.http.internal.common.*;
+import jdk.incubator.http.internal.frame.*;
+import jdk.incubator.http.internal.hpack.Encoder;
+import jdk.incubator.http.internal.hpack.Decoder;
+import jdk.incubator.http.internal.hpack.DecodingCallback;
+
+import static jdk.incubator.http.internal.frame.SettingsFrame.*;
+
+
+/**
+ * An Http2Connection. Encapsulates the socket(channel) and any SSLEngine used
+ * over it. Contains an HttpConnection which hides the SocketChannel SSL stuff.
+ *
+ * Http2Connections belong to a Http2ClientImpl, (one of) which belongs
+ * to a HttpClientImpl.
+ *
+ * Creation cases:
+ * 1) upgraded HTTP/1.1 plain tcp connection
+ * 2) prior knowledge directly created plain tcp connection
+ * 3) directly created HTTP/2 SSL connection which uses ALPN.
+ *
+ * Sending is done by writing directly to underlying HttpConnection object which
+ * is operating in async mode. No flow control applies on output at this level
+ * and all writes are just executed as puts to an output Q belonging to HttpConnection
+ * Flow control is implemented by HTTP/2 protocol itself.
+ *
+ * Hpack header compression
+ * and outgoing stream creation is also done here, because these operations
+ * must be synchronized at the socket level. Stream objects send frames simply
+ * by placing them on the connection's output Queue. sendFrame() is called
+ * from a higher level (Stream) thread.
+ *
+ * asyncReceive(ByteBuffer) is always called from the selector thread. It assembles
+ * incoming Http2Frames, and directs them to the appropriate Stream.incoming()
+ * or handles them directly itself. This thread performs hpack decompression
+ * and incoming stream creation (Server push). Incoming frames destined for a
+ * stream are provided by calling Stream.incoming().
+ */
+class Http2Connection  {
+
+
+    /*
+     *  ByteBuffer pooling strategy for HTTP/2 protocol:
+     *
+     * In general there are 4 points where ByteBuffers are used:
+     *  - incoming/outgoing frames from/to ByteBufers plus incoming/outgoing encrypted data
+     *    in case of SSL connection.
+     *
+     * 1. Outgoing frames encoded to ByteBuffers.
+     *    Outgoing ByteBuffers are created with requited size and frequently small (except DataFrames, etc)
+     *    At this place no pools at all. All outgoing buffers should be collected by GC.
+     *
+     * 2. Incoming ByteBuffers (decoded to frames).
+     *    Here, total elimination of BB pool is not a good idea.
+     *    We don't know how many bytes we will receive through network.
+     * So here we allocate buffer of reasonable size. The following life of the BB:
+     * - If all frames decoded from the BB are other than DataFrame and HeaderFrame (and HeaderFrame subclasses)
+     *     BB is returned to pool,
+     * - If we decoded DataFrame from the BB. In that case DataFrame refers to subbuffer obtained by slice() method.
+     *     Such BB is never returned to pool and will be GCed.
+     * - If we decoded HeadersFrame from the BB. Then header decoding is performed inside processFrame method and
+     *     the buffer could be release to pool.
+     *
+     * 3. SLL encrypted buffers. Here another pool was introduced and all net buffers are to/from the pool,
+     *    because of we can't predict size encrypted packets.
+     *
+     */
+
+
+    // A small class that allows to control the state of
+    // the connection preface. This is just a thin wrapper
+    // over a CountDownLatch.
+    private final class PrefaceController {
+        volatile boolean prefaceSent;
+        private final CountDownLatch latch = new CountDownLatch(1);
+
+        // This method returns immediately if the preface is sent,
+        // and blocks until the preface is sent if not.
+        // In the common case this where the preface is already sent
+        // this will cost not more than a volatile read.
+        void waitUntilPrefaceSent() {
+            if (!prefaceSent) {
+                try {
+                    // If the preface is not sent then await on the latch
+                    Log.logTrace("Waiting until connection preface is sent");
+                    latch.await();
+                    Log.logTrace("Preface sent: resuming reading");
+                    assert prefaceSent;
+                 } catch (InterruptedException e) {
+                    String msg = Utils.stackTrace(e);
+                    Log.logTrace(msg);
+                    shutdown(e);
+                }
+            }
+        }
+
+        // Mark that the connection preface is sent
+        void markPrefaceSent() {
+            assert !prefaceSent;
+            prefaceSent = true;
+            // Release the latch. If asyncReceive was scheduled it will
+            // be waiting for the release and will be woken up by this
+            // call. If not, then the semaphore will no longer be used after
+            // this.
+            latch.countDown();
+        }
+
+        boolean isPrefaceSent() {
+            return prefaceSent;
+        }
+    }
+
+    volatile boolean closed;
+
+    //-------------------------------------
+    final HttpConnection connection;
+    private final HttpClientImpl client;
+    private final Http2ClientImpl client2;
+    private final Map<Integer,Stream<?>> streams = new ConcurrentHashMap<>();
+    private int nextstreamid;
+    private int nextPushStream = 2;
+    private final Encoder hpackOut;
+    private final Decoder hpackIn;
+    final SettingsFrame clientSettings;
+    private volatile SettingsFrame serverSettings;
+    private final String key; // for HttpClientImpl.connections map
+    private final FramesDecoder framesDecoder;
+    private final FramesEncoder framesEncoder = new FramesEncoder();
+
+    /**
+     * Send Window controller for both connection and stream windows.
+     * Each of this connection's Streams MUST use this controller.
+     */
+    private final WindowController windowController = new WindowController();
+    private final PrefaceController prefaceController = new PrefaceController();
+    final WindowUpdateSender windowUpdater;
+
+    static final int DEFAULT_FRAME_SIZE = 16 * 1024;
+
+
+    // TODO: need list of control frames from other threads
+    // that need to be sent
+
+    private Http2Connection(HttpConnection connection,
+                            Http2ClientImpl client2,
+                            int nextstreamid,
+                            String key) {
+        this.connection = connection;
+        this.client = client2.client();
+        this.client2 = client2;
+        this.nextstreamid = nextstreamid;
+        this.key = key;
+        this.clientSettings = this.client2.getClientSettings();
+        this.framesDecoder = new FramesDecoder(this::processFrame, clientSettings.getParameter(SettingsFrame.MAX_FRAME_SIZE));
+        // serverSettings will be updated by server
+        this.serverSettings = SettingsFrame.getDefaultSettings();
+        this.hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
+        this.hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE));
+        this.windowUpdater = new ConnectionWindowUpdateSender(this, client.getReceiveBufferSize());
+    }
+        /**
+         * Case 1) Create from upgraded HTTP/1.1 connection.
+         * Is ready to use. Will not be SSL. exchange is the Exchange
+         * that initiated the connection, whose response will be delivered
+         * on a Stream.
+         */
+    Http2Connection(HttpConnection connection,
+                    Http2ClientImpl client2,
+                    Exchange<?> exchange,
+                    ByteBuffer initial)
+        throws IOException, InterruptedException
+    {
+        this(connection,
+                client2,
+                3, // stream 1 is registered during the upgrade
+                keyFor(connection));
+        assert !(connection instanceof SSLConnection);
+        Log.logTrace("Connection send window size {0} ", windowController.connectionWindowSize());
+
+        Stream<?> initialStream = createStream(exchange);
+        initialStream.registerStream(1);
+        windowController.registerStream(1, getInitialSendWindowSize());
+        initialStream.requestSent();
+        sendConnectionPreface();
+        // start reading and writing
+        // start reading
+        AsyncConnection asyncConn = (AsyncConnection)connection;
+        asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown, this::getReadBuffer);
+        connection.configureMode(Mode.ASYNC); // set mode only AFTER setAsyncCallbacks to provide visibility.
+        asyncReceive(ByteBufferReference.of(initial));
+        asyncConn.startReading();
+    }
+
+    // async style but completes immediately
+    static CompletableFuture<Http2Connection> createAsync(HttpConnection connection,
+                                                          Http2ClientImpl client2,
+                                                          Exchange<?> exchange,
+                                                          ByteBuffer initial) {
+        CompletableFuture<Http2Connection> cf = new MinimalFuture<>();
+        try {
+            Http2Connection c = new Http2Connection(connection, client2, exchange, initial);
+            cf.complete(c);
+        } catch (IOException | InterruptedException e) {
+            cf.completeExceptionally(e);
+        }
+        return cf;
+    }
+
+    /**
+     * Cases 2) 3)
+     *
+     * request is request to be sent.
+     */
+    Http2Connection(HttpRequestImpl request, Http2ClientImpl h2client)
+        throws IOException, InterruptedException
+    {
+        this(HttpConnection.getConnection(request.getAddress(h2client.client()), h2client.client(), request, true),
+                h2client,
+                1,
+                keyFor(request.uri(), request.proxy(h2client.client())));
+        Log.logTrace("Connection send window size {0} ", windowController.connectionWindowSize());
+
+        connection.connect();
+        // start reading
+        AsyncConnection asyncConn = (AsyncConnection)connection;
+        asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown, this::getReadBuffer);
+        connection.configureMode(Mode.ASYNC); // set mode only AFTER setAsyncCallbacks to provide visibility.
+        asyncConn.startReading();
+        sendConnectionPreface();
+    }
+
+    static String keyFor(HttpConnection connection) {
+        boolean isProxy = connection.isProxied();
+        boolean isSecure = connection.isSecure();
+        InetSocketAddress addr = connection.address();
+
+        return keyString(isSecure, isProxy, addr.getHostString(), addr.getPort());
+    }
+
+    static String keyFor(URI uri, InetSocketAddress proxy) {
+        boolean isSecure = uri.getScheme().equalsIgnoreCase("https");
+        boolean isProxy = proxy != null;
+
+        String host;
+        int port;
+
+        if (isProxy) {
+            host = proxy.getHostString();
+            port = proxy.getPort();
+        } else {
+            host = uri.getHost();
+            port = uri.getPort();
+        }
+        return keyString(isSecure, isProxy, host, port);
+    }
+
+    // {C,S}:{H:P}:host:port
+    // C indicates clear text connection "http"
+    // S indicates secure "https"
+    // H indicates host (direct) connection
+    // P indicates proxy
+    // Eg: "S:H:foo.com:80"
+    static String keyString(boolean secure, boolean proxy, String host, int port) {
+        return (secure ? "S:" : "C:") + (proxy ? "P:" : "H:") + host + ":" + port;
+    }
+
+    String key() {
+        return this.key;
+    }
+
+    void putConnection() {
+        client2.putConnection(this);
+    }
+
+    private static String toHexdump1(ByteBuffer bb) {
+        bb.mark();
+        StringBuilder sb = new StringBuilder(512);
+        Formatter f = new Formatter(sb);
+
+        while (bb.hasRemaining()) {
+            int i =  Byte.toUnsignedInt(bb.get());
+            f.format("%02x:", i);
+        }
+        sb.deleteCharAt(sb.length()-1);
+        bb.reset();
+        return sb.toString();
+    }
+
+    private static String toHexdump(ByteBuffer bb) {
+        List<String> words = new ArrayList<>();
+        int i = 0;
+        bb.mark();
+        while (bb.hasRemaining()) {
+            if (i % 2 == 0) {
+                words.add("");
+            }
+            byte b = bb.get();
+            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
+            words.set(i / 2, words.get(i / 2) + hex);
+            i++;
+        }
+        bb.reset();
+        return words.stream().collect(Collectors.joining(" "));
+    }
+
+    private void decodeHeaders(HeaderFrame frame, DecodingCallback decoder) {
+        boolean endOfHeaders = frame.getFlag(HeaderFrame.END_HEADERS);
+
+        ByteBufferReference[] buffers = frame.getHeaderBlock();
+        for (int i = 0; i < buffers.length; i++) {
+            hpackIn.decode(buffers[i].get(), endOfHeaders && (i == buffers.length - 1), decoder);
+        }
+    }
+
+    int getInitialSendWindowSize() {
+        return serverSettings.getParameter(INITIAL_WINDOW_SIZE);
+    }
+
+    void close() {
+        GoAwayFrame f = new GoAwayFrame(0, ErrorFrame.NO_ERROR, "Requested by user".getBytes());
+        // TODO: set last stream. For now zero ok.
+        sendFrame(f);
+    }
+
+    private ByteBufferPool readBufferPool = new ByteBufferPool();
+
+    // provides buffer to read data (default size)
+    public ByteBufferReference getReadBuffer() {
+        return readBufferPool.get(getMaxReceiveFrameSize() + Http2Frame.FRAME_HEADER_SIZE);
+    }
+
+    private final Object readlock = new Object();
+
+    public void asyncReceive(ByteBufferReference buffer) {
+        // We don't need to read anything and
+        // we don't want to send anything back to the server
+        // until the connection preface has been sent.
+        // Therefore we're going to wait if needed before reading
+        // (and thus replying) to anything.
+        // Starting to reply to something (e.g send an ACK to a
+        // SettingsFrame sent by the server) before the connection
+        // preface is fully sent might result in the server
+        // sending a GOAWAY frame with 'invalid_preface'.
+        prefaceController.waitUntilPrefaceSent();
+        synchronized (readlock) {
+            assert prefaceController.isPrefaceSent();
+            try {
+                framesDecoder.decode(buffer);
+            } catch (Throwable e) {
+                String msg = Utils.stackTrace(e);
+                Log.logTrace(msg);
+                shutdown(e);
+            }
+        }
+    }
+
+
+    void shutdown(Throwable t) {
+        Log.logError(t);
+        closed = true;
+        client2.deleteConnection(this);
+        List<Stream<?>> c = new LinkedList<>(streams.values());
+        for (Stream<?> s : c) {
+            s.cancelImpl(t);
+        }
+        connection.close();
+    }
+
+    /**
+     * Handles stream 0 (common) frames that apply to whole connection and passes
+     * other stream specific frames to that Stream object.
+     *
+     * Invokes Stream.incoming() which is expected to process frame without
+     * blocking.
+     */
+    void processFrame(Http2Frame frame) throws IOException {
+        Log.logFrames(frame, "IN");
+        int streamid = frame.streamid();
+        if (frame instanceof MalformedFrame) {
+            Log.logError(((MalformedFrame) frame).getMessage());
+            if (streamid == 0) {
+                protocolError(((MalformedFrame) frame).getErrorCode());
+            } else {
+                resetStream(streamid, ((MalformedFrame) frame).getErrorCode());
+            }
+            return;
+        }
+        if (streamid == 0) {
+            handleConnectionFrame(frame);
+        } else {
+            if (frame instanceof SettingsFrame) {
+                // The stream identifier for a SETTINGS frame MUST be zero
+                protocolError(GoAwayFrame.PROTOCOL_ERROR);
+                return;
+            }
+
+            Stream<?> stream = getStream(streamid);
+            if (stream == null) {
+                // Should never receive a frame with unknown stream id
+
+                // To avoid looping, an endpoint MUST NOT send a RST_STREAM in
+                // response to a RST_STREAM frame.
+                if (!(frame instanceof ResetFrame)) {
+                    resetStream(streamid, ResetFrame.PROTOCOL_ERROR);
+                }
+                return;
+            }
+            if (frame instanceof PushPromiseFrame) {
+                PushPromiseFrame pp = (PushPromiseFrame)frame;
+                handlePushPromise(stream, pp);
+            } else if (frame instanceof HeaderFrame) {
+                // decode headers (or continuation)
+                decodeHeaders((HeaderFrame) frame, stream.rspHeadersConsumer());
+                stream.incoming(frame);
+            } else {
+                stream.incoming(frame);
+            }
+        }
+    }
+
+    private <T> void handlePushPromise(Stream<T> parent, PushPromiseFrame pp)
+        throws IOException
+    {
+        HttpRequestImpl parentReq = parent.request;
+        int promisedStreamid = pp.getPromisedStream();
+        if (promisedStreamid != nextPushStream) {
+            resetStream(promisedStreamid, ResetFrame.PROTOCOL_ERROR);
+            return;
+        } else {
+            nextPushStream += 2;
+        }
+        HeaderDecoder decoder = new HeaderDecoder();
+        decodeHeaders(pp, decoder);
+        HttpHeadersImpl headers = decoder.headers();
+        HttpRequestImpl pushReq = HttpRequestImpl.createPushRequest(parentReq, headers);
+        Exchange<T> pushExch = new Exchange<>(pushReq, parent.exchange.multi);
+        Stream.PushedStream<?,T> pushStream = createPushStream(parent, pushExch);
+        pushExch.exchImpl = pushStream;
+        pushStream.registerStream(promisedStreamid);
+        parent.incoming_pushPromise(pushReq, pushStream);
+    }
+
+    private void handleConnectionFrame(Http2Frame frame)
+        throws IOException
+    {
+        switch (frame.type()) {
+          case SettingsFrame.TYPE:
+              handleSettings((SettingsFrame)frame);
+              break;
+          case PingFrame.TYPE:
+              handlePing((PingFrame)frame);
+              break;
+          case GoAwayFrame.TYPE:
+              handleGoAway((GoAwayFrame)frame);
+              break;
+          case WindowUpdateFrame.TYPE:
+              handleWindowUpdate((WindowUpdateFrame)frame);
+              break;
+          default:
+            protocolError(ErrorFrame.PROTOCOL_ERROR);
+        }
+    }
+
+    void resetStream(int streamid, int code) throws IOException {
+        Log.logError(
+            "Resetting stream {0,number,integer} with error code {1,number,integer}",
+            streamid, code);
+        ResetFrame frame = new ResetFrame(streamid, code);
+        sendFrame(frame);
+        closeStream(streamid);
+    }
+
+    void closeStream(int streamid) {
+        Stream<?> s = streams.remove(streamid);
+        // ## Remove s != null. It is a hack for delayed cancellation,reset
+        if (s != null && !(s instanceof Stream.PushedStream)) {
+            // Since PushStreams have no request body, then they have no
+            // corresponding entry in the window controller.
+            windowController.removeStream(streamid);
+        }
+    }
+    /**
+     * Increments this connection's send Window by the amount in the given frame.
+     */
+    private void handleWindowUpdate(WindowUpdateFrame f)
+        throws IOException
+    {
+        int amount = f.getUpdate();
+        if (amount <= 0) {
+            // ## temporarily disable to workaround a bug in Jetty where it
+            // ## sends Window updates with a 0 update value.
+            //protocolError(ErrorFrame.PROTOCOL_ERROR);
+        } else {
+            boolean success = windowController.increaseConnectionWindow(amount);
+            if (!success) {
+                protocolError(ErrorFrame.FLOW_CONTROL_ERROR);  // overflow
+            }
+        }
+    }
+
+    private void protocolError(int errorCode)
+        throws IOException
+    {
+        GoAwayFrame frame = new GoAwayFrame(0, errorCode);
+        sendFrame(frame);
+        shutdown(new IOException("protocol error"));
+    }
+
+    private void handleSettings(SettingsFrame frame)
+        throws IOException
+    {
+        assert frame.streamid() == 0;
+        if (!frame.getFlag(SettingsFrame.ACK)) {
+            int oldWindowSize = serverSettings.getParameter(INITIAL_WINDOW_SIZE);
+            int newWindowSize = frame.getParameter(INITIAL_WINDOW_SIZE);
+            int diff = newWindowSize - oldWindowSize;
+            if (diff != 0) {
+                windowController.adjustActiveStreams(diff);
+            }
+            serverSettings = frame;
+            sendFrame(new SettingsFrame(SettingsFrame.ACK));
+        }
+    }
+
+    private void handlePing(PingFrame frame)
+        throws IOException
+    {
+        frame.setFlag(PingFrame.ACK);
+        sendUnorderedFrame(frame);
+    }
+
+    private void handleGoAway(GoAwayFrame frame)
+        throws IOException
+    {
+        shutdown(new IOException(
+                        String.valueOf(connection.channel().getLocalAddress())
+                        +": GOAWAY received"));
+    }
+
+    /**
+     * Max frame size we are allowed to send
+     */
+    public int getMaxSendFrameSize() {
+        int param = serverSettings.getParameter(MAX_FRAME_SIZE);
+        if (param == -1) {
+            param = DEFAULT_FRAME_SIZE;
+        }
+        return param;
+    }
+
+    /**
+     * Max frame size we will receive
+     */
+    public int getMaxReceiveFrameSize() {
+        return clientSettings.getParameter(MAX_FRAME_SIZE);
+    }
+
+    // Not sure how useful this is.
+    public int getMaxHeadersSize() {
+        return serverSettings.getParameter(MAX_HEADER_LIST_SIZE);
+    }
+
+    private static final String CLIENT_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
+
+    private static final byte[] PREFACE_BYTES =
+        CLIENT_PREFACE.getBytes(StandardCharsets.ISO_8859_1);
+
+    /**
+     * Sends Connection preface and Settings frame with current preferred
+     * values
+     */
+    private void sendConnectionPreface() throws IOException {
+        Log.logTrace("{0}: start sending connection preface to {1}",
+                     connection.channel().getLocalAddress(),
+                     connection.address());
+        SettingsFrame sf = client2.getClientSettings();
+        ByteBufferReference ref = framesEncoder.encodeConnectionPreface(PREFACE_BYTES, sf);
+        Log.logFrames(sf, "OUT");
+        // send preface bytes and SettingsFrame together
+        connection.write(ref.get());
+
+        Log.logTrace("PREFACE_BYTES sent");
+        Log.logTrace("Settings Frame sent");
+
+        // send a Window update for the receive buffer we are using
+        // minus the initial 64 K specified in protocol
+        final int len = client2.client().getReceiveBufferSize() - (64 * 1024 - 1);
+        windowUpdater.sendWindowUpdate(len);
+        Log.logTrace("finished sending connection preface");
+        prefaceController.markPrefaceSent();
+    }
+
+    /**
+     * Returns an existing Stream with given id, or null if doesn't exist
+     */
+    @SuppressWarnings("unchecked")
+    <T> Stream<T> getStream(int streamid) {
+        return (Stream<T>)streams.get(streamid);
+    }
+
+    /**
+     * Creates Stream with given id.
+     */
+    <T> Stream<T> createStream(Exchange<T> exchange) {
+        Stream<T> stream = new Stream<>(client, this, exchange, windowController);
+        return stream;
+    }
+
+    <T> Stream.PushedStream<?,T> createPushStream(Stream<T> parent, Exchange<T> pushEx) {
+        PushGroup<?,T> pg = parent.exchange.getPushGroup();
+        return new Stream.PushedStream<>(pg, client, this, parent, pushEx);
+    }
+
+    <T> void putStream(Stream<T> stream, int streamid) {
+        streams.put(streamid, stream);
+    }
+
+    void deleteStream(int streamid) {
+        streams.remove(streamid);
+        windowController.removeStream(streamid);
+    }
+
+    /**
+     * Encode the headers into a List<ByteBuffer> and then create HEADERS
+     * and CONTINUATION frames from the list and return the List<Http2Frame>.
+     */
+    private List<HeaderFrame> encodeHeaders(OutgoingHeaders<Stream<?>> frame) {
+        List<ByteBufferReference> buffers = encodeHeadersImpl(
+                getMaxSendFrameSize(),
+                frame.getAttachment().getRequestPseudoHeaders(),
+                frame.getUserHeaders(),
+                frame.getSystemHeaders());
+
+        List<HeaderFrame> frames = new ArrayList<>(buffers.size());
+        Iterator<ByteBufferReference> bufIterator = buffers.iterator();
+        HeaderFrame oframe = new HeadersFrame(frame.streamid(), frame.getFlags(), bufIterator.next());
+        frames.add(oframe);
+        while(bufIterator.hasNext()) {
+            oframe = new ContinuationFrame(frame.streamid(), bufIterator.next());
+            frames.add(oframe);
+        }
+        oframe.setFlag(HeaderFrame.END_HEADERS);
+        return frames;
+    }
+
+    // Dedicated cache for headers encoding ByteBuffer.
+    // There can be no concurrent access to this  buffer as all access to this buffer
+    // and its content happen within a single critical code block section protected
+    // by the sendLock. / (see sendFrame())
+    private ByteBufferPool headerEncodingPool = new ByteBufferPool();
+
+    private ByteBufferReference getHeaderBuffer(int maxFrameSize) {
+        ByteBufferReference ref = headerEncodingPool.get(maxFrameSize);
+        ref.get().limit(maxFrameSize);
+        return ref;
+    }
+
+    /*
+     * Encodes all the headers from the given HttpHeaders into the given List
+     * of buffers.
+     *
+     * From https://tools.ietf.org/html/rfc7540#section-8.1.2 :
+     *
+     *     ...Just as in HTTP/1.x, header field names are strings of ASCII
+     *     characters that are compared in a case-insensitive fashion.  However,
+     *     header field names MUST be converted to lowercase prior to their
+     *     encoding in HTTP/2...
+     */
+    private List<ByteBufferReference> encodeHeadersImpl(int maxFrameSize, HttpHeaders... headers) {
+        ByteBufferReference buffer = getHeaderBuffer(maxFrameSize);
+        List<ByteBufferReference> buffers = new ArrayList<>();
+        for(HttpHeaders header : headers) {
+            for (Map.Entry<String, List<String>> e : header.map().entrySet()) {
+                String lKey = e.getKey().toLowerCase();
+                List<String> values = e.getValue();
+                for (String value : values) {
+                    hpackOut.header(lKey, value);
+                    while (!hpackOut.encode(buffer.get())) {
+                        buffer.get().flip();
+                        buffers.add(buffer);
+                        buffer =  getHeaderBuffer(maxFrameSize);
+                    }
+                }
+            }
+        }
+        buffer.get().flip();
+        buffers.add(buffer);
+        return buffers;
+    }
+
+    private ByteBufferReference[] encodeHeaders(OutgoingHeaders<Stream<?>> oh, Stream<?> stream) {
+        oh.streamid(stream.streamid);
+        if (Log.headers()) {
+            StringBuilder sb = new StringBuilder("HEADERS FRAME (stream=");
+            sb.append(stream.streamid).append(")\n");
+            Log.dumpHeaders(sb, "    ", oh.getAttachment().getRequestPseudoHeaders());
+            Log.dumpHeaders(sb, "    ", oh.getSystemHeaders());
+            Log.dumpHeaders(sb, "    ", oh.getUserHeaders());
+            Log.logHeaders(sb.toString());
+        }
+        List<HeaderFrame> frames = encodeHeaders(oh);
+        return encodeFrames(frames);
+    }
+
+    private ByteBufferReference[] encodeFrames(List<HeaderFrame> frames) {
+        if (Log.frames()) {
+            frames.forEach(f -> Log.logFrames(f, "OUT"));
+        }
+        return framesEncoder.encodeFrames(frames);
+    }
+
+    static Throwable getExceptionFrom(CompletableFuture<?> cf) {
+        try {
+            cf.get();
+            return null;
+        } catch (Throwable e) {
+            if (e.getCause() != null) {
+                return e.getCause();
+            } else {
+                return e;
+            }
+        }
+    }
+
+    private Stream<?> registerNewStream(OutgoingHeaders<Stream<?>> oh) {
+        Stream<?> stream = oh.getAttachment();
+        int streamid = nextstreamid;
+        nextstreamid += 2;
+        stream.registerStream(streamid);
+        // set outgoing window here. This allows thread sending
+        // body to proceed.
+        windowController.registerStream(streamid, getInitialSendWindowSize());
+        return stream;
+    }
+
+    private final Object sendlock = new Object();
+
+    void sendFrame(Http2Frame frame) {
+        try {
+            synchronized (sendlock) {
+                if (frame instanceof OutgoingHeaders) {
+                    @SuppressWarnings("unchecked")
+                    OutgoingHeaders<Stream<?>> oh = (OutgoingHeaders<Stream<?>>) frame;
+                    Stream<?> stream = registerNewStream(oh);
+                    // provide protection from inserting unordered frames between Headers and Continuation
+                    connection.writeAsync(encodeHeaders(oh, stream));
+                } else {
+                    connection.writeAsync(encodeFrame(frame));
+                }
+            }
+            connection.flushAsync();
+        } catch (IOException e) {
+            if (!closed) {
+                Log.logError(e);
+                shutdown(e);
+            }
+        }
+    }
+
+    private ByteBufferReference[] encodeFrame(Http2Frame frame) {
+        Log.logFrames(frame, "OUT");
+        return framesEncoder.encodeFrame(frame);
+    }
+
+    void sendDataFrame(DataFrame frame) {
+        try {
+            connection.writeAsync(encodeFrame(frame));
+            connection.flushAsync();
+        } catch (IOException e) {
+            if (!closed) {
+                Log.logError(e);
+                shutdown(e);
+            }
+        }
+    }
+
+    /*
+     * Direct call of the method bypasses synchronization on "sendlock" and
+     * allowed only of control frames: WindowUpdateFrame, PingFrame and etc.
+     * prohibited for such frames as DataFrame, HeadersFrame, ContinuationFrame.
+     */
+    void sendUnorderedFrame(Http2Frame frame) {
+        try {
+            connection.writeAsyncUnordered(encodeFrame(frame));
+            connection.flushAsync();
+        } catch (IOException e) {
+            if (!closed) {
+                Log.logError(e);
+                shutdown(e);
+            }
+        }
+    }
+
+    static class HeaderDecoder implements DecodingCallback {
+        HttpHeadersImpl headers;
+
+        HeaderDecoder() {
+            this.headers = new HttpHeadersImpl();
+        }
+
+        @Override
+        public void onDecoded(CharSequence name, CharSequence value) {
+            headers.addHeader(name.toString(), value.toString());
+        }
+
+        HttpHeadersImpl headers() {
+            return headers;
+        }
+    }
+
+    static final class ConnectionWindowUpdateSender extends WindowUpdateSender {
+
+        public ConnectionWindowUpdateSender(Http2Connection connection,
+                                            int initialWindowSize) {
+            super(connection, initialWindowSize);
+        }
+
+        @Override
+        int getStreamId() {
+            return 0;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.CookieManager;
+import java.net.InetSocketAddress;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+
+/**
+ * A container for configuration information common to multiple {@link
+ * HttpRequest}s. All requests are sent through a {@code HttpClient}.
+ *
+ * <p> {@code HttpClient}s are immutable and created from a builder returned
+ * from {@link HttpClient#newBuilder()}. Request builders are created by calling
+ * {@link HttpRequest#newBuilder() }.
+ * <p>
+ * See {@link HttpRequest} for examples of usage of this API.
+ *
+ * @since 9
+ */
+public abstract class HttpClient {
+
+    /**
+     * Creates an HttpClient.
+     */
+    protected HttpClient() {}
+
+    /**
+     * Returns a new HttpClient with default settings.
+     *
+     * @return a new HttpClient
+     */
+    public static HttpClient newHttpClient() {
+        return new HttpClientBuilderImpl().build();
+    }
+
+    /**
+     * Creates a new {@code HttpClient} builder.
+     *
+     * @return a {@code HttpClient.Builder}
+     */
+    public static Builder newBuilder() {
+        return new HttpClientBuilderImpl();
+    }
+
+    /**
+     * A builder of immutable {@link HttpClient}s. {@code HttpClient.Builder}s
+     * are created by calling {@link HttpClient#newBuilder() }
+     *
+     * <p> Each of the setter methods in this class modifies the state of the
+     * builder and returns <i>this</i> (ie. the same instance). The methods are
+     * not synchronized and should not be called from multiple threads without
+     * external synchronization.
+     *
+     * <p> {@link #build()} returns a new {@code HttpClient} each time it is
+     * called.
+     *
+     * @since 9
+     */
+    public abstract static class Builder {
+
+        protected Builder() {}
+
+        /**
+         * Sets a cookie manager.
+         *
+         * @param cookieManager the cookie manager
+         * @return this builder
+         */
+        public abstract Builder cookieManager(CookieManager cookieManager);
+
+        /**
+         * Sets an {@code SSLContext}. If a security manager is set, then the caller
+         * must have the {@link java.net.NetPermission NetPermission}
+         * ({@code "setSSLContext"})
+         *
+         * <p> The effect of not calling this method, is that a default {@link
+         * javax.net.ssl.SSLContext} is used, which is normally adequate for
+         * client applications that do not need to specify protocols, or require
+         * client authentication.
+         *
+         * @param sslContext the SSLContext
+         * @return this builder
+         * @throws SecurityException if a security manager is set and the
+         *                           caller does not have any required permission
+         */
+        public abstract Builder sslContext(SSLContext sslContext);
+
+        /**
+         * Sets an {@code SSLParameters}. If this method is not called, then a default
+         * set of parameters are used. The contents of the given object are
+         * copied. Some parameters which are used internally by the HTTP protocol
+         * implementation (such as application protocol list) should not be set
+         * by callers, as they are ignored.
+         *
+         * @param sslParameters the SSLParameters
+         * @return this builder
+         */
+        public abstract Builder sslParameters(SSLParameters sslParameters);
+
+        /**
+         * Sets the executor to be used for asynchronous tasks. If this method is
+         * not called, a default executor is set, which is the one returned from {@link
+         * java.util.concurrent.Executors#newCachedThreadPool()
+         * Executors.newCachedThreadPool}.
+         *
+         * @param executor the Executor
+         * @return this builder
+         */
+        public abstract Builder executor(Executor executor);
+
+        /**
+         * Specifies whether requests will automatically follow redirects issued
+         * by the server. This setting can be overridden on each request. The
+         * default value for this setting is {@link Redirect#NEVER NEVER}
+         *
+         * @param policy the redirection policy
+         * @return this builder
+         */
+        public abstract Builder followRedirects(Redirect policy);
+
+        /**
+         * Requests a specific HTTP protocol version where possible. If not set,
+         * the version defaults to {@link HttpClient.Version#HTTP_1_1}. If
+         * {@link HttpClient.Version#HTTP_2} is set, then each request will
+         * attempt to upgrade to HTTP/2.  If the upgrade succeeds, then the
+         * response to this request will use HTTP/2 and all subsequent requests
+         * and responses to the same
+         * <a href="https://tools.ietf.org/html/rfc6454#section-4">origin server</a>
+         * will use HTTP/2. If the upgrade fails, then the response will be
+         * handled using HTTP/1.1
+         *
+         * @param version the requested HTTP protocol version
+         * @return this builder
+         */
+        public abstract Builder version(HttpClient.Version version);
+
+        /**
+         * Sets the default priority for any HTTP/2 requests sent from this
+         * client. The value provided must be between {@code 1} and {@code 256}
+         * (inclusive).
+         *
+         * @param priority the priority weighting
+         * @return this builder
+         * @throws IllegalArgumentException if the given priority is out of range
+         */
+        public abstract Builder priority(int priority);
+
+        /**
+         * Sets a {@link java.net.ProxySelector} for this client. If no selector
+         * is set, then no proxies are used. If a {@code null} parameter is
+         * given then the system wide default proxy selector is used.
+         *
+         * @implNote {@link java.net.ProxySelector#of(InetSocketAddress)}
+         * provides a {@code ProxySelector} which uses one proxy for all requests.
+         *
+         * @param selector the ProxySelector
+         * @return this builder
+         */
+        public abstract Builder proxy(ProxySelector selector);
+
+        /**
+         * Sets an authenticator to use for HTTP authentication.
+         *
+         * @param a the Authenticator
+         * @return this builder
+         */
+        public abstract Builder authenticator(Authenticator a);
+
+        /**
+         * Returns a {@link HttpClient} built from the current state of this
+         * builder.
+         *
+         * @return this builder
+         */
+        public abstract HttpClient build();
+    }
+
+
+    /**
+     * Returns an {@code Optional} which contains this client's {@link
+     * CookieManager}. If no {@code CookieManager} was set in this client's builder,
+     * then the {@code Optional} is empty.
+     *
+     * @return an {@code Optional} containing this client's {@code CookieManager}
+     */
+    public abstract Optional<CookieManager> cookieManager();
+
+    /**
+     * Returns the follow-redirects setting for this client. The default value
+     * for this setting is {@link HttpClient.Redirect#NEVER}
+     *
+     * @return this client's follow redirects setting
+     */
+    public abstract Redirect followRedirects();
+
+    /**
+     * Returns an {@code Optional} containing the {@code ProxySelector} for this client.
+     * If no proxy is set then the {@code Optional} is empty.
+     *
+     * @return an {@code Optional} containing this client's proxy selector
+     */
+    public abstract Optional<ProxySelector> proxy();
+
+    /**
+     * Returns the {@code SSLContext}, if one was set on this client. If a security
+     * manager is set, then the caller must have the
+     * {@link java.net.NetPermission NetPermission}("getSSLContext") permission.
+     * If no {@code SSLContext} was set, then the default context is returned.
+     *
+     * @return this client's SSLContext
+     * @throws SecurityException if the caller does not have permission to get
+     *         the SSLContext
+     */
+    public abstract SSLContext sslContext();
+
+    /**
+     * Returns an {@code Optional} containing the {@link SSLParameters} set on
+     * this client. If no {@code SSLParameters} were set in the client's builder,
+     * then the {@code Optional} is empty.
+     *
+     * @return an {@code Optional} containing this client's {@code SSLParameters}
+     */
+    public abstract Optional<SSLParameters> sslParameters();
+
+    /**
+     * Returns an {@code Optional} containing the {@link Authenticator} set on
+     * this client. If no {@code Authenticator} was set in the client's builder,
+     * then the {@code Optional} is empty.
+     *
+     * @return an {@code Optional} containing this client's {@code Authenticator}
+     */
+    public abstract Optional<Authenticator> authenticator();
+
+    /**
+     * Returns the HTTP protocol version requested for this client. The default
+     * value is {@link HttpClient.Version#HTTP_1_1}
+     *
+     * @return the HTTP protocol version requested
+     */
+    public abstract HttpClient.Version version();
+
+    /**
+     * Returns the {@code Executor} set on this client. If an {@code
+     * Executor} was not set on the client's builder, then a default
+     * object is returned. The default {@code Executor} is created independently
+     * for each client.
+     *
+     * @return this client's Executor
+     */
+    public abstract Executor executor();
+
+    /**
+     * The HTTP protocol version.
+     *
+     * @since 9
+     */
+    public enum Version {
+
+        /**
+         * HTTP version 1.1
+         */
+        HTTP_1_1,
+
+        /**
+         * HTTP version 2
+         */
+        HTTP_2
+    }
+
+    /**
+     * Defines automatic redirection policy. This is checked whenever a {@code 3XX}
+     * response code is received. If redirection does not happen automatically
+     * then the response is returned to the user, where it can be handled
+     * manually.
+     *
+     * <p> {@code Redirect} policy is set via the {@link
+     * HttpClient.Builder#followRedirects(HttpClient.Redirect)} method.
+     *
+     * @since 9
+     */
+    public enum Redirect {
+
+        /**
+         * Never redirect.
+         */
+        NEVER,
+
+        /**
+         * Always redirect.
+         */
+        ALWAYS,
+
+        /**
+         * Redirect to same protocol only. Redirection may occur from HTTP URLs
+         * to other HTTP URLs, and from HTTPS URLs to other HTTPS URLs.
+         */
+        SAME_PROTOCOL,
+
+        /**
+         * Redirect always except from HTTPS URLs to HTTP URLs.
+         */
+        SECURE
+    }
+
+    /**
+     * Sends the given request using this client, blocking if necessary to get
+     * the response. The returned {@link HttpResponse}{@code <T>} contains the
+     * response status, headers, and body ( as handled by given response body
+     * handler ).
+     *
+     * @param <T> the response body type
+     * @param req the request
+     * @param responseBodyHandler the response body handler
+     * @return the response body
+     * @throws java.io.IOException if an I/O error occurs when sending or receiving
+     * @throws java.lang.InterruptedException if the operation is interrupted
+     */
+    public abstract <T> HttpResponse<T>
+    send(HttpRequest req, HttpResponse.BodyHandler<T> responseBodyHandler)
+        throws IOException, InterruptedException;
+
+    /**
+     * Sends the given request asynchronously using this client and the given
+     * response handler.
+     *
+     * @param <T> the response body type
+     * @param req the request
+     * @param responseBodyHandler the response body handler
+     * @return a {@code CompletableFuture<HttpResponse<T>>}
+     */
+    public abstract <T> CompletableFuture<HttpResponse<T>>
+    sendAsync(HttpRequest req, HttpResponse.BodyHandler<T> responseBodyHandler);
+
+    /**
+     * Sends the given request asynchronously using this client and the given
+     * multi response handler.
+     *
+     * @param <U> a type representing the aggregated results
+     * @param <T> a type representing all of the response bodies
+     * @param req the request
+     * @param multiProcessor the MultiProcessor for the request
+     * @return a {@code CompletableFuture<U>}
+     */
+    public abstract <U, T> CompletableFuture<U>
+    sendAsync(HttpRequest req, HttpResponse.MultiProcessor<U, T> multiProcessor);
+
+    /**
+     * Creates a builder of {@link WebSocket} instances connected to the given
+     * URI and receiving events and messages with the given {@code Listener}.
+     *
+     * <p> <b>Example</b>
+     * <pre>{@code
+     *     HttpClient client = HttpClient.newHttpClient();
+     *     WebSocket.Builder builder = client.newWebSocketBuilder(
+     *             URI.create("ws://websocket.example.com"),
+     *             listener);
+     * }</pre>
+     *
+     * <p> Finer control over the WebSocket Opening Handshake can be achieved
+     * by using a custom {@code HttpClient}.
+     *
+     * <p> <b>Example</b>
+     * <pre>{@code
+     *     InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
+     *     HttpClient client = HttpClient.newBuilder()
+     *             .proxy(ProxySelector.of(addr))
+     *             .build();
+     *     WebSocket.Builder builder = client.newWebSocketBuilder(
+     *             URI.create("ws://websocket.example.com"),
+     *             listener);
+     * }</pre>
+     *
+     * @implSpec The default implementation of this method throws {@code
+     * UnsupportedOperationException}. However, clients obtained through
+     * {@link HttpClient#newHttpClient()} or {@link HttpClient#newBuilder()}
+     * provide WebSocket capability.
+     *
+     * @param uri
+     *         the WebSocket URI
+     * @param listener
+     *         the listener
+     *
+     * @return a builder of {@code WebSocket} instances
+     * @throws UnsupportedOperationException
+     *         if this {@code HttpClient} does not provide WebSocket support
+     */
+    public WebSocket.Builder newWebSocketBuilder(URI uri,
+                                                 WebSocket.Listener listener)
+    {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientBuilderImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.net.Authenticator;
+import java.net.CookieManager;
+import java.net.ProxySelector;
+import java.util.concurrent.Executor;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import jdk.incubator.http.internal.common.Utils;
+import static java.util.Objects.requireNonNull;
+
+class HttpClientBuilderImpl extends HttpClient.Builder {
+
+    CookieManager cookieManager;
+    HttpClient.Redirect followRedirects;
+    ProxySelector proxy;
+    Authenticator authenticator;
+    HttpClient.Version version = HttpClient.Version.HTTP_1_1;
+    Executor executor;
+    // Security parameters
+    SSLContext sslContext;
+    SSLParameters sslParams;
+    int priority = -1;
+
+    @Override
+    public HttpClientBuilderImpl cookieManager(CookieManager cookieManager) {
+        requireNonNull(cookieManager);
+        this.cookieManager = cookieManager;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl sslContext(SSLContext sslContext) {
+        requireNonNull(sslContext);
+        Utils.checkNetPermission("setSSLContext");
+        this.sslContext = sslContext;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl sslParameters(SSLParameters sslParameters) {
+        requireNonNull(sslParameters);
+        this.sslParams = sslParameters;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl executor(Executor s) {
+        requireNonNull(s);
+        this.executor = s;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl followRedirects(HttpClient.Redirect policy) {
+        requireNonNull(policy);
+        this.followRedirects = policy;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl version(HttpClient.Version version) {
+        requireNonNull(version);
+        this.version = version;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl priority(int priority) {
+        if (priority < 1 || priority > 256) {
+            throw new IllegalArgumentException("priority must be between 1 and 256");
+        }
+        this.priority = priority;
+        return this;
+    }
+
+    @Override
+    public HttpClientBuilderImpl proxy(ProxySelector proxy) {
+        requireNonNull(proxy);
+        this.proxy = proxy;
+        return this;
+    }
+
+
+    @Override
+    public HttpClientBuilderImpl authenticator(Authenticator a) {
+        requireNonNull(a);
+        this.authenticator = a;
+        return this;
+    }
+
+    @Override
+    public HttpClient build() {
+        return HttpClientImpl.create(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.net.Authenticator;
+import java.net.CookieManager;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.security.NoSuchAlgorithmException;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.stream.Stream;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.Utils;
+import jdk.incubator.http.internal.websocket.BuilderImpl;
+
+/**
+ * Client implementation. Contains all configuration information and also
+ * the selector manager thread which allows async events to be registered
+ * and delivered when they occur. See AsyncEvent.
+ */
+class HttpClientImpl extends HttpClient {
+
+    // Define the default factory as a static inner class
+    // that embeds all the necessary logic to avoid
+    // the risk of using a lambda that might keep a reference on the
+    // HttpClient instance from which it was created (helps with
+    // heapdump analysis).
+    private static final class DefaultThreadFactory implements ThreadFactory {
+        private DefaultThreadFactory() {}
+        @Override
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(null, r, "HttpClient_worker", 0, true);
+            t.setDaemon(true);
+            return t;
+        }
+        static final ThreadFactory INSTANCE = new DefaultThreadFactory();
+    }
+
+    private final CookieManager cookieManager;
+    private final Redirect followRedirects;
+    private final ProxySelector proxySelector;
+    private final Authenticator authenticator;
+    private final Version version;
+    private final ConnectionPool connections;
+    private final Executor executor;
+    // Security parameters
+    private final SSLContext sslContext;
+    private final SSLParameters sslParams;
+    private final SelectorManager selmgr;
+    private final FilterFactory filters;
+    private final Http2ClientImpl client2;
+
+    /** A Set of, deadline first, ordered timeout events. */
+    private final TreeSet<TimeoutEvent> timeouts;
+
+    public static HttpClientImpl create(HttpClientBuilderImpl builder) {
+        HttpClientImpl impl = new HttpClientImpl(builder);
+        impl.start();
+        return impl;
+    }
+
+    private HttpClientImpl(HttpClientBuilderImpl builder) {
+        if (builder.sslContext == null) {
+            try {
+                sslContext = SSLContext.getDefault();
+            } catch (NoSuchAlgorithmException ex) {
+                throw new InternalError(ex);
+            }
+        } else {
+            sslContext = builder.sslContext;
+        }
+        Executor ex = builder.executor;
+        if (ex == null) {
+            ex = Executors.newCachedThreadPool(DefaultThreadFactory.INSTANCE);
+        } else {
+            ex = builder.executor;
+        }
+        client2 = new Http2ClientImpl(this);
+        executor = ex;
+        cookieManager = builder.cookieManager;
+        followRedirects = builder.followRedirects == null ?
+                Redirect.NEVER : builder.followRedirects;
+        this.proxySelector = builder.proxy;
+        authenticator = builder.authenticator;
+        version = builder.version;
+        if (builder.sslParams == null) {
+            sslParams = getDefaultParams(sslContext);
+        } else {
+            sslParams = builder.sslParams;
+        }
+        connections = new ConnectionPool();
+        connections.start();
+        timeouts = new TreeSet<>();
+        try {
+            selmgr = new SelectorManager(this);
+        } catch (IOException e) {
+            // unlikely
+            throw new InternalError(e);
+        }
+        selmgr.setDaemon(true);
+        filters = new FilterFactory();
+        initFilters();
+    }
+
+    private void start() {
+        selmgr.start();
+    }
+
+    private static SSLParameters getDefaultParams(SSLContext ctx) {
+        SSLParameters params = ctx.getSupportedSSLParameters();
+        params.setProtocols(new String[]{"TLSv1.2"});
+        return params;
+    }
+
+    /**
+     * Wait for activity on given exchange (assuming blocking = false).
+     * It's a no-op if blocking = true. In particular, the following occurs
+     * in the SelectorManager thread.
+     *
+     *  1) mark the connection non-blocking
+     *  2) add to selector
+     *  3) If selector fires for this exchange then
+     *  4)   - mark connection as blocking
+     *  5)   - call AsyncEvent.handle()
+     *
+     * If exchange needs to block again, then call registerEvent() again
+     */
+    void registerEvent(AsyncEvent exchange) throws IOException {
+        selmgr.register(exchange);
+    }
+
+    /**
+     * Only used from RawChannel to disconnect the channel from
+     * the selector
+     */
+    void cancelRegistration(SocketChannel s) {
+        selmgr.cancel(s);
+    }
+
+
+    Http2ClientImpl client2() {
+        return client2;
+    }
+
+    /*
+    @Override
+    public ByteBuffer getBuffer() {
+        return pool.getBuffer();
+    }
+
+    // SSL buffers are larger. Manage separately
+
+    int size = 16 * 1024;
+
+    ByteBuffer getSSLBuffer() {
+        return ByteBuffer.allocate(size);
+    }
+
+    /**
+     * Return a new buffer that's a bit bigger than the given one
+     *
+     * @param buf
+     * @return
+     *
+    ByteBuffer reallocSSLBuffer(ByteBuffer buf) {
+        size = buf.capacity() * 12 / 10; // 20% bigger
+        return ByteBuffer.allocate(size);
+    }
+
+    synchronized void returnSSLBuffer(ByteBuffer buf) {
+        if (buf.capacity() >= size)
+           sslBuffers.add(0, buf);
+    }
+
+    @Override
+    public void returnBuffer(ByteBuffer buffer) {
+        pool.returnBuffer(buffer);
+    }
+    */
+
+    @Override
+    public <T> HttpResponse<T>
+    send(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler)
+        throws IOException, InterruptedException
+    {
+        MultiExchange<Void,T> mex = new MultiExchange<>(req, this, responseHandler);
+        return mex.response();
+    }
+
+    @Override
+    public <T> CompletableFuture<HttpResponse<T>>
+    sendAsync(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler)
+    {
+        MultiExchange<Void,T> mex = new MultiExchange<>(req, this, responseHandler);
+        return mex.responseAsync(null)
+                  .thenApply((HttpResponseImpl<T> b) -> (HttpResponse<T>) b);
+    }
+
+    @Override
+    public <U, T> CompletableFuture<U>
+    sendAsync(HttpRequest req, HttpResponse.MultiProcessor<U, T> responseHandler) {
+        MultiExchange<U,T> mex = new MultiExchange<>(req, this, responseHandler);
+        return mex.multiResponseAsync();
+    }
+
+    // new impl. Should get rid of above
+    /*
+    static class BufferPool implements BufferHandler {
+
+        final LinkedList<ByteBuffer> freelist = new LinkedList<>();
+
+        @Override
+        public synchronized ByteBuffer getBuffer() {
+            ByteBuffer buf;
+
+            while (!freelist.isEmpty()) {
+                buf = freelist.removeFirst();
+                buf.clear();
+                return buf;
+            }
+            return ByteBuffer.allocate(BUFSIZE);
+        }
+
+        @Override
+        public synchronized void returnBuffer(ByteBuffer buffer) {
+            assert buffer.capacity() > 0;
+            freelist.add(buffer);
+        }
+    }
+
+    static BufferPool pool = new BufferPool();
+
+    static BufferHandler pool() {
+        return pool;
+    }
+*/
+    // Main loop for this client's selector
+    private final static class SelectorManager extends Thread {
+
+        private static final long NODEADLINE = 3000L;
+        private final Selector selector;
+        private volatile boolean closed;
+        private final List<AsyncEvent> readyList;
+        private final List<AsyncEvent> registrations;
+
+        // Uses a weak reference to the HttpClient owning this
+        // selector: a strong reference prevents its garbage
+        // collection while the thread is running.
+        // We want the thread to exit gracefully when the
+        // HttpClient that owns it gets GC'ed.
+        WeakReference<HttpClientImpl> ownerRef;
+
+        SelectorManager(HttpClientImpl ref) throws IOException {
+            super(null, null, "SelectorManager", 0, false);
+            ownerRef = new WeakReference<>(ref);
+            readyList = new ArrayList<>();
+            registrations = new ArrayList<>();
+            selector = Selector.open();
+        }
+
+        // This returns immediately. So caller not allowed to send/receive
+        // on connection.
+
+        synchronized void register(AsyncEvent e) throws IOException {
+            registrations.add(e);
+            selector.wakeup();
+        }
+
+        synchronized void cancel(SocketChannel e) {
+            SelectionKey key = e.keyFor(selector);
+            if (key != null) {
+                key.cancel();
+            }
+            selector.wakeup();
+        }
+
+        void wakeupSelector() {
+            selector.wakeup();
+        }
+
+        synchronized void shutdown() {
+            closed = true;
+            try {
+                selector.close();
+            } catch (IOException ignored) { }
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (!Thread.currentThread().isInterrupted()) {
+                    HttpClientImpl client;
+                    synchronized (this) {
+                        for (AsyncEvent exchange : registrations) {
+                            SelectableChannel c = exchange.channel();
+                            try {
+                                c.configureBlocking(false);
+                                SelectionKey key = c.keyFor(selector);
+                                SelectorAttachment sa;
+                                if (key == null) {
+                                    sa = new SelectorAttachment(c, selector);
+                                } else {
+                                    sa = (SelectorAttachment) key.attachment();
+                                }
+                                sa.register(exchange);
+                            } catch (IOException e) {
+                                Log.logError("HttpClientImpl: " + e);
+                                c.close();
+                                // let the exchange deal with it
+                                handleEvent(exchange);
+                            }
+                        }
+                        registrations.clear();
+                    }
+
+                    // Check whether client is still alive, and if not,
+                    // gracefully stop this thread
+                    if ((client = ownerRef.get()) == null) {
+                        Log.logTrace("HttpClient no longer referenced. Exiting...");
+                        return;
+                    }
+                    long millis = client.purgeTimeoutsAndReturnNextDeadline();
+                    client = null; // don't hold onto the client ref
+
+                    //debugPrint(selector);
+                    // Don't wait for ever as it might prevent the thread to
+                    // stop gracefully. millis will be 0 if no deadline was found.
+                    int n = selector.select(millis == 0 ? NODEADLINE : millis);
+                    if (n == 0) {
+                        // Check whether client is still alive, and if not,
+                        // gracefully stop this thread
+                        if ((client = ownerRef.get()) == null) {
+                            Log.logTrace("HttpClient no longer referenced. Exiting...");
+                            return;
+                        }
+                        client.purgeTimeoutsAndReturnNextDeadline();
+                        client = null; // don't hold onto the client ref
+                        continue;
+                    }
+                    Set<SelectionKey> keys = selector.selectedKeys();
+
+                    for (SelectionKey key : keys) {
+                        SelectorAttachment sa = (SelectorAttachment) key.attachment();
+                        int eventsOccurred = key.readyOps();
+                        sa.events(eventsOccurred).forEach(readyList::add);
+                        sa.resetInterestOps(eventsOccurred);
+                    }
+                    selector.selectNow(); // complete cancellation
+                    selector.selectedKeys().clear();
+
+                    for (AsyncEvent exchange : readyList) {
+                        if (exchange.blocking()) {
+                            exchange.channel().configureBlocking(true);
+                        }
+                        handleEvent(exchange); // will be delegated to executor
+                    }
+                    readyList.clear();
+                }
+            } catch (Throwable e) {
+                if (!closed) {
+                    // This terminates thread. So, better just print stack trace
+                    String err = Utils.stackTrace(e);
+                    Log.logError("HttpClientImpl: fatal error: " + err);
+                }
+            } finally {
+                shutdown();
+            }
+        }
+
+        void debugPrint(Selector selector) {
+            System.err.println("Selector: debugprint start");
+            Set<SelectionKey> keys = selector.keys();
+            for (SelectionKey key : keys) {
+                SelectableChannel c = key.channel();
+                int ops = key.interestOps();
+                System.err.printf("selector chan:%s ops:%d\n", c, ops);
+            }
+            System.err.println("Selector: debugprint end");
+        }
+
+        void handleEvent(AsyncEvent e) {
+            if (closed) {
+                e.abort();
+            } else {
+                e.handle();
+            }
+        }
+    }
+
+    /**
+     * Tracks multiple user level registrations associated with one NIO
+     * registration (SelectionKey). In this implementation, registrations
+     * are one-off and when an event is posted the registration is cancelled
+     * until explicitly registered again.
+     *
+     * <p> No external synchronization required as this class is only used
+     * by the SelectorManager thread. One of these objects required per
+     * connection.
+     */
+    private static class SelectorAttachment {
+        private final SelectableChannel chan;
+        private final Selector selector;
+        private final ArrayList<AsyncEvent> pending;
+        private int interestOps;
+
+        SelectorAttachment(SelectableChannel chan, Selector selector) {
+            this.pending = new ArrayList<>();
+            this.chan = chan;
+            this.selector = selector;
+        }
+
+        void register(AsyncEvent e) throws ClosedChannelException {
+            int newOps = e.interestOps();
+            boolean reRegister = (interestOps & newOps) != newOps;
+            interestOps |= newOps;
+            pending.add(e);
+            if (reRegister) {
+                // first time registration happens here also
+                chan.register(selector, interestOps, this);
+            }
+        }
+
+        /**
+         * Returns a Stream<AsyncEvents> containing only events that are
+         * registered with the given {@code interestOps}.
+         */
+        Stream<AsyncEvent> events(int interestOps) {
+            return pending.stream()
+                    .filter(ev -> (ev.interestOps() & interestOps) != 0);
+        }
+
+        /**
+         * Removes any events with the given {@code interestOps}, and if no
+         * events remaining, cancels the associated SelectionKey.
+         */
+        void resetInterestOps(int interestOps) {
+            int newOps = 0;
+
+            Iterator<AsyncEvent> itr = pending.iterator();
+            while (itr.hasNext()) {
+                AsyncEvent event = itr.next();
+                int evops = event.interestOps();
+                if (event.repeating()) {
+                    newOps |= evops;
+                    continue;
+                }
+                if ((evops & interestOps) != 0) {
+                    itr.remove();
+                } else {
+                    newOps |= evops;
+                }
+            }
+
+            this.interestOps = newOps;
+            SelectionKey key = chan.keyFor(selector);
+            if (newOps == 0) {
+                key.cancel();
+            } else {
+                key.interestOps(newOps);
+            }
+        }
+    }
+
+    @Override
+    public SSLContext sslContext() {
+        Utils.checkNetPermission("getSSLContext");
+        return sslContext;
+    }
+
+    @Override
+    public Optional<SSLParameters> sslParameters() {
+        return Optional.ofNullable(sslParams);
+    }
+
+    @Override
+    public Optional<Authenticator> authenticator() {
+        return Optional.ofNullable(authenticator);
+    }
+
+    @Override
+    public Executor executor() {
+        return executor;
+    }
+
+    ConnectionPool connectionPool() {
+        return connections;
+    }
+
+    @Override
+    public Redirect followRedirects() {
+        return followRedirects;
+    }
+
+
+    @Override
+    public Optional<CookieManager> cookieManager() {
+        return Optional.ofNullable(cookieManager);
+    }
+
+    @Override
+    public Optional<ProxySelector> proxy() {
+        return Optional.ofNullable(this.proxySelector);
+    }
+
+    @Override
+    public WebSocket.Builder newWebSocketBuilder(URI uri,
+                                                 WebSocket.Listener listener) {
+        return new BuilderImpl(this, uri, listener);
+    }
+
+    @Override
+    public Version version() {
+        return version;
+    }
+
+    //private final HashMap<String, Boolean> http2NotSupported = new HashMap<>();
+
+    boolean getHttp2Allowed() {
+        return version.equals(Version.HTTP_2);
+    }
+
+    private void initFilters() {
+        addFilter(AuthenticationFilter.class);
+        addFilter(RedirectFilter.class);
+        if (this.cookieManager != null) {
+            addFilter(CookieFilter.class);
+        }
+    }
+
+    private void addFilter(Class<? extends HeaderFilter> f) {
+        filters.addFilter(f);
+    }
+
+    final List<HeaderFilter> filterChain() {
+        return filters.getFilterChain();
+    }
+
+    // Timer controls.
+    // Timers are implemented through timed Selector.select() calls.
+
+    synchronized void registerTimer(TimeoutEvent event) {
+        timeouts.add(event);
+        selmgr.wakeupSelector();
+    }
+
+    synchronized void cancelTimer(TimeoutEvent event) {
+        timeouts.stream().filter(e -> e == event).forEach(timeouts::remove);
+    }
+
+    /**
+     * Purges ( handles ) timer events that have passed their deadline, and
+     * returns the amount of time, in milliseconds, until the next earliest
+     * event. A return value of 0 means that there are no events.
+     */
+    private synchronized long purgeTimeoutsAndReturnNextDeadline() {
+        if (timeouts.isEmpty())
+            return 0L;
+
+        Instant now = Instant.now();
+        Iterator<TimeoutEvent> itr = timeouts.iterator();
+        while (itr.hasNext()) {
+            TimeoutEvent event = itr.next();
+            long diff = now.until(event.deadline(), ChronoUnit.MILLIS);
+            if (diff <= 0) {
+                itr.remove();
+                event.handle();  // TODO: release lock.
+            } else {
+                return diff;
+            }
+        }
+        return 0L;
+    }
+
+    // used for the connection window
+    int getReceiveBufferSize() {
+        return Utils.getIntegerNetProperty(
+                "jdk.httpclient.connectionWindowSize", 256 * 1024
+        );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import javax.net.ssl.SSLParameters;
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * Wraps socket channel layer and takes care of SSL also.
+ *
+ * Subtypes are:
+ *      PlainHttpConnection: regular direct TCP connection to server
+ *      PlainProxyConnection: plain text proxy connection
+ *      PlainTunnelingConnection: opens plain text (CONNECT) tunnel to server
+ *      SSLConnection: TLS channel direct to server
+ *      SSLTunnelConnection: TLS channel via (CONNECT) proxy tunnel
+ */
+abstract class HttpConnection implements Closeable {
+
+    enum Mode {
+        BLOCKING,
+        NON_BLOCKING,
+        ASYNC
+    }
+
+    protected Mode mode;
+
+    // address we are connected to. Could be a server or a proxy
+    final InetSocketAddress address;
+    final HttpClientImpl client;
+
+    HttpConnection(InetSocketAddress address, HttpClientImpl client) {
+        this.address = address;
+        this.client = client;
+    }
+
+    /**
+     * Public API to this class. addr is the ultimate destination. Any proxies
+     * etc are figured out from the request. Returns an instance of one of the
+     * following
+     *      PlainHttpConnection
+     *      PlainTunnelingConnection
+     *      SSLConnection
+     *      SSLTunnelConnection
+     *
+     * When object returned, connect() or connectAsync() must be called, which
+     * when it returns/completes, the connection is usable for requests.
+     */
+    public static HttpConnection getConnection(
+            InetSocketAddress addr, HttpClientImpl client, HttpRequestImpl request)
+    {
+        return getConnectionImpl(addr, client, request, false);
+    }
+
+    /**
+     * Called specifically to get an async connection for HTTP/2 over SSL.
+     */
+    public static HttpConnection getConnection(InetSocketAddress addr,
+        HttpClientImpl client, HttpRequestImpl request, boolean isHttp2) {
+
+        return getConnectionImpl(addr, client, request, isHttp2);
+    }
+
+    public abstract void connect() throws IOException, InterruptedException;
+
+    public abstract CompletableFuture<Void> connectAsync();
+
+    /**
+     * Returns whether this connection is connected to its destination
+     */
+    abstract boolean connected();
+
+    abstract boolean isSecure();
+
+    abstract boolean isProxied();
+
+    /**
+     * Completes when the first byte of the response is available to be read.
+     */
+    abstract CompletableFuture<Void> whenReceivingResponse();
+
+    final boolean isOpen() {
+        return channel().isOpen();
+    }
+
+    /* Returns either a plain HTTP connection or a plain tunnelling connection
+     * for proxied websockets */
+    private static HttpConnection getPlainConnection(InetSocketAddress addr,
+                                                     InetSocketAddress proxy,
+                                                     HttpRequestImpl request,
+                                                     HttpClientImpl client) {
+        if (request.isWebSocket() && proxy != null) {
+            return new PlainTunnelingConnection(addr, proxy, client);
+        } else {
+            if (proxy == null) {
+                return new PlainHttpConnection(addr, client);
+            } else {
+                return new PlainProxyConnection(proxy, client);
+            }
+        }
+    }
+
+    private static HttpConnection getSSLConnection(InetSocketAddress addr,
+            InetSocketAddress proxy, HttpRequestImpl request,
+            String[] alpn, boolean isHttp2, HttpClientImpl client)
+    {
+        if (proxy != null) {
+            return new SSLTunnelConnection(addr, client, proxy);
+        } else if (!isHttp2) {
+            return new SSLConnection(addr, client, alpn);
+        } else {
+            return new AsyncSSLConnection(addr, client, alpn);
+        }
+    }
+
+    /**
+     * Main factory method.   Gets a HttpConnection, either cached or new if
+     * none available.
+     */
+    private static HttpConnection getConnectionImpl(InetSocketAddress addr,
+            HttpClientImpl client,
+            HttpRequestImpl request, boolean isHttp2)
+    {
+        HttpConnection c;
+        InetSocketAddress proxy = request.proxy(client);
+        boolean secure = request.secure();
+        ConnectionPool pool = client.connectionPool();
+        String[] alpn =  null;
+
+        if (secure && client.version() == HttpClient.Version.HTTP_2) {
+            alpn = new String[1];
+            alpn[0] = "h2";
+        }
+
+        if (!secure) {
+            c = pool.getConnection(false, addr, proxy);
+            if (c != null) {
+                return c;
+            } else {
+                return getPlainConnection(addr, proxy, request, client);
+            }
+        } else {
+            c = pool.getConnection(true, addr, proxy);
+            if (c != null) {
+                return c;
+            } else {
+                return getSSLConnection(addr, proxy, request, alpn, isHttp2, client);
+            }
+        }
+    }
+
+    void returnToCache(HttpHeaders hdrs) {
+        if (hdrs == null) {
+            // the connection was closed by server
+            close();
+            return;
+        }
+        if (!isOpen()) {
+            return;
+        }
+        ConnectionPool pool = client.connectionPool();
+        boolean keepAlive = hdrs.firstValue("Connection")
+                .map((s) -> !s.equalsIgnoreCase("close"))
+                .orElse(true);
+
+        if (keepAlive) {
+            pool.returnToPool(this);
+        } else {
+            close();
+        }
+    }
+
+    /**
+     * Also check that the number of bytes written is what was expected. This
+     * could be different if the buffer is user-supplied and its internal
+     * pointers were manipulated in a race condition.
+     */
+    final void checkWrite(long expected, ByteBuffer buffer) throws IOException {
+        long written = write(buffer);
+        if (written != expected) {
+            throw new IOException("incorrect number of bytes written");
+        }
+    }
+
+    final void checkWrite(long expected,
+                          ByteBuffer[] buffers,
+                          int start,
+                          int length)
+        throws IOException
+    {
+        long written = write(buffers, start, length);
+        if (written != expected) {
+            throw new IOException("incorrect number of bytes written");
+        }
+    }
+
+    abstract SocketChannel channel();
+
+    final InetSocketAddress address() {
+        return address;
+    }
+
+    synchronized void configureMode(Mode mode) throws IOException {
+        this.mode = mode;
+        if (mode == Mode.BLOCKING) {
+            channel().configureBlocking(true);
+        } else {
+            channel().configureBlocking(false);
+        }
+    }
+
+    synchronized Mode getMode() {
+        return mode;
+    }
+
+    abstract ConnectionPool.CacheKey cacheKey();
+
+    // overridden in SSL only
+    SSLParameters sslParameters() {
+        return null;
+    }
+
+    // Methods to be implemented for Plain TCP and SSL
+
+    abstract long write(ByteBuffer[] buffers, int start, int number)
+        throws IOException;
+
+    abstract long write(ByteBuffer buffer) throws IOException;
+
+    // Methods to be implemented for Plain TCP (async mode) and AsyncSSL
+
+    /**
+     * In {@linkplain Mode#ASYNC async mode}, this method puts buffers at the
+     * end of the send queue; Otherwise, it is equivalent to {@link
+     * #write(ByteBuffer[], int, int) write(buffers, 0, buffers.length)}.
+     * When in async mode, calling this method should later be followed by
+     * subsequent flushAsync invocation.
+     * That allows multiple threads to put buffers into the queue while some other
+     * thread is writing.
+     */
+    abstract void writeAsync(ByteBufferReference[] buffers) throws IOException;
+
+    /**
+     * In {@linkplain Mode#ASYNC async mode}, this method may put
+     * buffers at the beginning of send queue, breaking frames sequence and
+     * allowing to write these buffers before other buffers in the queue;
+     * Otherwise, it is equivalent to {@link
+     * #write(ByteBuffer[], int, int) write(buffers, 0, buffers.length)}.
+     * When in async mode, calling this method should later be followed by
+     * subsequent flushAsync invocation.
+     * That allows multiple threads to put buffers into the queue while some other
+     * thread is writing.
+     */
+    abstract void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException;
+
+    /**
+     * This method should be called after  any writeAsync/writeAsyncUnordered
+     * invocation.
+     * If there is a race to flushAsync from several threads one thread
+     * (race winner) capture flush operation and write the whole queue content.
+     * Other threads (race losers) exits from the method (not blocking)
+     * and continue execution.
+     */
+    abstract void flushAsync() throws IOException;
+
+    /**
+     * Closes this connection, by returning the socket to its connection pool.
+     */
+    @Override
+    public abstract void close();
+
+    abstract void shutdownInput() throws IOException;
+
+    abstract void shutdownOutput() throws IOException;
+
+    /**
+     * Puts position to limit and limit to capacity so we can resume reading
+     * into this buffer, but if required > 0 then limit may be reduced so that
+     * no more than required bytes are read next time.
+     */
+    static void resumeChannelRead(ByteBuffer buf, int required) {
+        int limit = buf.limit();
+        buf.position(limit);
+        int capacity = buf.capacity() - limit;
+        if (required > 0 && required < capacity) {
+            buf.limit(limit + required);
+        } else {
+            buf.limit(buf.capacity());
+        }
+    }
+
+    final int read(ByteBuffer buffer) throws IOException {
+        return readImpl(buffer);
+    }
+
+    final ByteBuffer read() throws IOException {
+        return readImpl();
+    }
+
+    /*
+     * Returns a ByteBuffer with the data available at the moment, or null if
+     * reached EOF.
+     */
+    protected abstract ByteBuffer readImpl() throws IOException;
+
+    /** Reads as much as possible into given buffer and returns amount read. */
+    protected abstract int readImpl(ByteBuffer buffer) throws IOException;
+
+    @Override
+    public String toString() {
+        return "HttpConnection: " + channel().toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpHeaders.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.OptionalLong;
+
+/**
+ * A read-only view of a set of HTTP headers.
+ *
+ * @since 9
+ */
+public interface HttpHeaders {
+
+    /**
+     * Returns an {@link java.util.Optional} containing the first value of the
+     * given named (and possibly multi-valued) header. If the header is not
+     * present, then the returned {@code Optional} is empty.
+     *
+     * @param name the header name
+     * @return an {@code Optional<String>} for the first named value
+     */
+    public Optional<String> firstValue(String name);
+
+    /**
+     * Returns an {@link java.util.OptionalLong} containing the first value of the
+     * named header field. If the header is not
+     * present, then the Optional is empty. If the header is present but
+     * contains a value that does not parse as a {@code Long} value, then an
+     * exception is thrown.
+     *
+     * @param name the header name
+     * @return  an {@code OptionalLong}
+     * @throws NumberFormatException if a value is found, but does not parse as
+     *                               a Long
+     */
+    public OptionalLong firstValueAsLong(String name);
+
+    /**
+     * Returns an unmodifiable List of all of the values of the given named
+     * header. Always returns a List, which may be empty if the header is not
+     * present.
+     *
+     * @param name the header name
+     * @return a List of String values
+     */
+    public List<String> allValues(String name);
+
+    /**
+     * Returns an unmodifiable multi Map view of this HttpHeaders. This
+     * interface should only be used when it is required to iterate over the
+     * entire set of headers.
+     *
+     * @return the Map
+     */
+    public Map<String,List<String>> map();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpRequest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.charset.*;
+import java.nio.file.Path;
+import java.time.Duration;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Flow;
+import java.util.function.Supplier;
+
+/**
+ * Represents one HTTP request which can be sent to a server. {@code
+ * HttpRequest}s are built from {@code HttpRequest} {@link HttpRequest.Builder
+ * builder}s. {@code HttpRequest} builders are obtained
+ * by calling {@link HttpRequest#newBuilder(java.net.URI) HttpRequest.newBuilder}.
+ * A request's {@link java.net.URI}, headers and body can be set. Request bodies
+ * are provided through a {@link BodyProcessor} object supplied to the
+ * {@link Builder#DELETE(jdk.incubator.http.HttpRequest.BodyProcessor) DELETE},
+ * {@link Builder#POST(jdk.incubator.http.HttpRequest.BodyProcessor) POST} or
+ * {@link Builder#PUT(jdk.incubator.http.HttpRequest.BodyProcessor) PUT} methods.
+ * {@link Builder#GET() GET} does not take a body. Once all required
+ * parameters have been set in the builder, {@link Builder#build() } is called
+ * to return the {@code HttpRequest}. Builders can also be copied
+ * and modified multiple times in order to build multiple related requests that
+ * differ in some parameters.
+ *
+ * <p> Two simple, example HTTP interactions are shown below:
+ * <pre>
+ * {@code
+ *      HttpClient client = HttpClient.newHttpClient();
+ *
+ *      // GET
+ *      HttpResponse<String> response = client.send(
+ *          HttpRequest
+ *              .newBuilder(new URI("http://www.foo.com/"))
+ *              .headers("Foo", "foovalue", "Bar", "barvalue")
+ *              .GET()
+ *              .build(),
+ *          BodyHandler.asString()
+ *      );
+ *      int statusCode = response.statusCode();
+ *      String body = response.body();
+ *
+ *      // POST
+ *      HttpResponse<Path> response = client.send(
+ *          HttpRequest
+ *              .newBuilder(new URI("http://www.foo.com/"))
+ *              .headers("Foo", "foovalue", "Bar", "barvalue")
+ *              .POST(BodyProcessor.fromString("Hello world"))
+ *              .build(),
+ *          BodyHandler.asFile(Paths.get("/path"))
+ *      );
+ *      int statusCode = response.statusCode();
+ *      Path body = response.body(); // should be "/path"
+ * }
+ * </pre>
+ * <p> The request is sent and the response obtained by calling one of the
+ * following methods in {@link HttpClient}.
+ * <ul><li>{@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler)} blocks
+ * until the entire request has been sent and the response has been received.</li>
+ * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.BodyHandler)} sends the
+ * request and receives the response asynchronously. Returns immediately with a
+ * {@link java.util.concurrent.CompletableFuture CompletableFuture}&lt;{@link
+ * HttpResponse}&gt;.</li>
+ * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.MultiProcessor) }
+ * sends the request asynchronously, expecting multiple responses. This
+ * capability is of most relevance to HTTP/2 server push, but can be used for
+ * single responses (HTTP/1.1 or HTTP/2) also.</li>
+ * </ul>
+ *
+ * <p> Once a {@link HttpResponse} is received, the headers, response code
+ * and body (typically) are available. Whether the body has been read or not
+ * depends on the type {@code <T>} of the response body. See below.
+ *
+ * <p> See below for discussion of synchronous versus asynchronous usage.
+ *
+ * <p> <b>Request bodies</b>
+ *
+ * <p> Request bodies are sent using one of the request processor implementations
+ * below provided in {@link HttpRequest.BodyProcessor}, or else a custom implementation can be
+ * used.
+ * <ul>
+ * <li>{@link BodyProcessor#fromByteArray(byte[]) fromByteArray(byte[])} from byte array</li>
+ * <li>{@link BodyProcessor#fromByteArrays(Iterable) fromByteArrays(Iterable)}
+ *      from an Iterable of byte arrays</li>
+ * <li>{@link BodyProcessor#fromFile(java.nio.file.Path) fromFile(Path)} from the file located
+ *     at the given Path</li>
+ * <li>{@link BodyProcessor#fromString(java.lang.String) fromString(String)} from a String </li>
+ * <li>{@link BodyProcessor#fromInputStream(Supplier) fromInputStream}({@link Supplier}&lt;
+ *      {@link InputStream}&gt;) from an InputStream obtained from a Supplier</li>
+ * <li>{@link BodyProcessor#noBody() } no request body is sent</li>
+ * </ul>
+ *
+ * <p> <b>Response bodies</b>
+ *
+ * <p>Responses bodies are handled at two levels. When sending the request,
+ * a response body handler is specified. This is a function ({@link HttpResponse.BodyHandler})
+ * which will be called with the response status code and headers, once these are received. This
+ * function is then expected to return a {@link HttpResponse.BodyProcessor}
+ * {@code <T>} which is then used to read the response body converting it
+ * into an instance of T. After this occurs, the response becomes
+ * available in a {@link HttpResponse} and {@link HttpResponse#body()} can then
+ * be called to obtain the body. Some implementations and examples of usage of both {@link
+ * HttpResponse.BodyProcessor} and {@link HttpResponse.BodyHandler}
+ * are provided in {@link HttpResponse}:
+ * <p><b>Some of the pre-defined body handlers</b><br>
+ * <ul>
+ * <li>{@link HttpResponse.BodyHandler#asByteArray() BodyHandler.asByteArray()}
+ * stores the body in a byte array</li>
+ * <li>{@link HttpResponse.BodyHandler#asString() BodyHandler.asString()}
+ * stores the body as a String </li>
+ * <li>{@link HttpResponse.BodyHandler#asFile(java.nio.file.Path)
+ * BodyHandler.asFile(Path)} stores the body in a named file</li>
+ * <li>{@link HttpResponse.BodyHandler#discard(Object) BodyHandler.discard()}
+ * discards the response body and returns the given value instead.</li>
+ * </ul>
+ *
+ * <p> <b>Multi responses</b>
+ *
+ * <p> With HTTP/2 it is possible for a server to return a main response and zero
+ * or more additional responses (known as server pushes) to a client-initiated
+ * request. These are handled using a special response processor called {@link
+ * HttpResponse.MultiProcessor}.
+ *
+ * <p> <b>Blocking/asynchronous behavior and thread usage</b>
+ *
+ * <p> There are two styles of request sending: <i>synchronous</i> and
+ * <i>asynchronous</i>. {@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler) }
+ * blocks the calling thread until the request has been sent and the response received.
+ *
+ * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.BodyHandler)}  is asynchronous and returns
+ * immediately with a {@link java.util.concurrent.CompletableFuture}&lt;{@link
+ * HttpResponse}&gt; and when this object completes (in a background thread) the
+ * response has been received.
+ *
+ * <p> {@link HttpClient#sendAsync(HttpRequest,HttpResponse.MultiProcessor)}
+ * is the variant for multi responses and is also asynchronous.
+ *
+ * <p> {@code CompletableFuture}s can be combined in different ways to declare the
+ * dependencies among several asynchronous tasks, while allowing for the maximum
+ * level of parallelism to be utilized.
+ *
+ * <p> <b>Security checks</b>
+ *
+ * <p> If a security manager is present then security checks are performed by
+ * the sending methods. A {@link java.net.URLPermission} or {@link java.net.SocketPermission} is required to
+ * access any destination origin server and proxy server utilised. {@code URLPermission}s
+ * should be preferred in policy files over {@code SocketPermission}s given the more
+ * limited scope of {@code URLPermission}. Permission is always implicitly granted to a
+ * system's default proxies. The {@code URLPermission} form used to access proxies uses
+ * a method parameter of {@code "CONNECT"} (for all kinds of proxying) and a url string
+ * of the form {@code "socket://host:port"} where host and port specify the proxy's
+ * address.
+ *
+ * <p> <b>Examples</b>
+ * <pre>{@code
+ *      HttpClient client = HttpClient
+ *              .newBuilder()
+ *              .build();
+ *
+ *      HttpRequest request = HttpRequest
+ *              .newBuilder(new URI("http://www.foo.com/"))
+ *              .POST(BodyProcessor.fromString("Hello world"))
+ *              .build();
+ *
+ *      HttpResponse<Path> response =
+ *          client.send(request, BodyHandler.asFile(Paths.get("/path")));
+ *
+ *      Path body = response.body();
+ * }</pre>
+ *
+ * <p><b>Asynchronous Example</b>
+ *
+ * <p> The above example will work asynchronously, if {@link HttpClient#sendAsync
+ * (HttpRequest, HttpResponse.BodyHandler) sendAsync} is used instead of
+ * {@link HttpClient#send(HttpRequest,HttpResponse.BodyHandler) send}
+ * in which case the returned object is a {@link CompletableFuture}{@code <HttpResponse>}
+ * instead of {@link HttpResponse}. The following example shows how multiple requests
+ * can be sent asynchronously. It also shows how dependent asynchronous operations
+ * (receiving response, and receiving response body) can be chained easily using
+ * one of the many methods in {@code CompletableFuture}.
+ * <pre>
+ * {@code
+ *  // fetch a list of target URIs asynchronously and store them in Files.
+ *
+ *      List<URI> targets = ...
+ *
+ *      List<CompletableFuture<File>> futures = targets
+ *          .stream()
+ *          .map(target -> client
+ *                  .sendAsync(
+ *                      HttpRequest.newBuilder(target)
+ *                                 .GET()
+ *                                 .build(),
+ *                      BodyHandler.asFile(Paths.get("base", target.getPath())))
+ *                  .thenApply(response -> response.body())
+ *                  .thenApply(path -> path.toFile()))
+ *          .collect(Collectors.toList());
+ *
+ *      // all async operations waited for here
+ *
+ *      CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]))
+ *          .join();
+ *
+ *      // all elements of futures have completed and can be examined.
+ *      // Use File.exists() to check whether file was successfully downloaded
+ * }
+ * </pre>
+ * <p>
+ * Unless otherwise stated, {@code null} parameter values will cause methods
+ * of this class to throw {@code NullPointerException}.
+ *
+ * @since 9
+ */
+public abstract class HttpRequest {
+
+    /**
+     * Creates an HttpRequest.
+     */
+    protected HttpRequest() {}
+
+    /**
+     * A builder of {@link HttpRequest}s. {@code HttpRequest.Builder}s are
+     * created by calling {@link HttpRequest#newBuilder(URI)} or {@link
+     * HttpRequest#newBuilder()}.
+     *
+     * <p> Each of the setter methods in this class modifies the state of the
+     * builder and returns <i>this</i> (ie. the same instance). The methods are
+     * not synchronized and should not be called from multiple threads without
+     * external synchronization.
+     * <p>Note, that not all request headers may be set by user code. Some are
+     * restricted for security reasons and others such as the headers relating
+     * to authentication, redirection and cookie management are managed by
+     * specific APIs rather than through directly user set headers.
+     *
+     * <p> The {@linkplain #build() build} method returns a new {@code
+     * HttpRequest} each time it is invoked.
+     *
+     * @since 9
+     */
+    public abstract static class Builder {
+
+        /**
+         * Creates a Builder.
+         */
+        protected Builder() {}
+
+        /**
+         * Sets this {@code HttpRequest}'s request {@code URI}.
+         *
+         * @param uri the request URI
+         * @return this request builder
+         * @throws IllegalArgumentException if the {@code URI} scheme is not
+         *         supported.
+         */
+        public abstract Builder uri(URI uri);
+
+        /**
+         * Request server to acknowledge request before sending request
+         * body. This is disabled by default. If enabled, the server is requested
+         * to send an error response or a {@code 100 Continue} response before the client
+         * sends the request body. This means the request processor for the
+         * request will not be invoked until this interim response is received.
+         *
+         * @param enable {@code true} if Expect continue to be sent
+         * @return this request builder
+         */
+        public abstract Builder expectContinue(boolean enable);
+
+        /**
+         * Overrides the {@link HttpClient#version()  } setting for this
+         * request. This sets the version requested. The corresponding
+         * {@link HttpResponse} should be checked for the version that was
+         * used.
+         *
+         * @param version the HTTP protocol version requested
+         * @return this request builder
+         */
+        public abstract Builder version(HttpClient.Version version);
+
+        /**
+         * Adds the given name value pair to the set of headers for this request.
+         *
+         * @param name the header name
+         * @param value the header value
+         * @return this request builder
+         */
+        public abstract Builder header(String name, String value);
+
+//        /**
+//         * Overrides the {@code ProxySelector} set on the request's client for this
+//         * request.
+//         *
+//         * @param proxy the ProxySelector to use
+//         * @return this request builder
+//         */
+//        public abstract Builder proxy(ProxySelector proxy);
+
+        /**
+         * Adds the given name value pairs to the set of headers for this
+         * request. The supplied {@code String}s must alternate as names and values.
+         *
+         * @param headers the list of String name value pairs
+         * @return this request builder
+         * @throws IllegalArgumentException if there is an odd number of
+         *                                  parameters
+         */
+        // TODO (spec): consider signature change
+        // public abstract Builder headers(java.util.Map.Entry<String,String>... headers);
+        public abstract Builder headers(String... headers);
+
+        /**
+         * Sets a timeout for this request. If the response is not received
+         * within the specified timeout then a {@link HttpTimeoutException} is
+         * thrown from {@link HttpClient#send(jdk.incubator.http.HttpRequest,
+         * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::send} or
+         * {@link HttpClient#sendAsync(jdk.incubator.http.HttpRequest,
+         * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::sendAsync}
+         * completes exceptionally with a {@code HttpTimeoutException}. The effect
+         * of not setting a timeout is the same as setting an infinite Duration, ie.
+         * block forever.
+         *
+         * @param duration
+         * @return this request builder
+         */
+        public abstract Builder timeout(Duration duration);
+
+        /**
+         * Sets the given name value pair to the set of headers for this
+         * request. This overwrites any previously set values for name.
+         *
+         * @param name the header name
+         * @param value the header value
+         * @return this request builder
+         */
+        public abstract Builder setHeader(String name, String value);
+
+        /**
+         * Sets the request method of this builder to GET.
+         *
+         * @return a {@code HttpRequest}
+         */
+        public abstract Builder GET();
+
+        /**
+         * Sets the request method of this builder to POST and sets its
+         * request body processor to the given value.
+         *
+         * @param body the body processor
+         *
+         * @return a {@code HttpRequest}
+         */
+        public abstract Builder POST(BodyProcessor body);
+
+        /**
+         * Sets the request method of this builder to PUT and sets its
+         * request body processor to the given value.
+         *
+         * @param body the body processor
+         *
+         * @return a {@code HttpRequest}
+         */
+        public abstract Builder PUT(BodyProcessor body);
+
+        /**
+         * Sets the request method of this builder to DELETE and sets its
+         * request body processor to the given value.
+         *
+         * @param body the body processor
+         *
+         * @return a {@code HttpRequest}
+         */
+
+        public abstract Builder DELETE(BodyProcessor body);
+
+        /**
+         * Sets the request method and request body of this builder to the
+         * given values.
+         *
+         * @param body the body processor
+         * @param method the method to use
+         * @return a {@code HttpRequest}
+         * @throws IllegalArgumentException if an unrecognized method is used
+         */
+        public abstract Builder method(String method, BodyProcessor body);
+
+        /**
+         * Builds and returns a {@link HttpRequest}.
+         *
+         * @return the request
+         */
+        public abstract HttpRequest build();
+
+        /**
+         * Returns an exact duplicate copy of this {@code Builder} based on current
+         * state. The new builder can then be modified independently of this
+         * builder.
+         *
+         * @return an exact copy of this Builder
+         */
+        public abstract Builder copy();
+    }
+
+    /**
+     * Creates a {@code HttpRequest} builder.
+     *
+     * @param uri the request URI
+     * @return a new request builder
+     * @throws IllegalArgumentException if the URI scheme is not supported.
+     */
+    public static HttpRequest.Builder newBuilder(URI uri) {
+        return new HttpRequestBuilderImpl(uri);
+    }
+
+    /**
+     * Creates a {@code HttpRequest} builder.
+     *
+     * @return a new request builder
+     */
+    public static HttpRequest.Builder newBuilder() {
+        return new HttpRequestBuilderImpl();
+    }
+
+    /**
+     * Returns an {@code Optional} containing the {@link BodyProcessor}
+     * set on this request. If no {@code BodyProcessor} was set in the
+     * requests's builder, then the {@code Optional} is empty.
+     *
+     * @return an {@code Optional} containing this request's
+     *         {@code BodyProcessor}
+     */
+    public abstract Optional<BodyProcessor> bodyProcessor();
+
+    /**
+     * Returns the request method for this request. If not set explicitly,
+     * the default method for any request is "GET".
+     *
+     * @return this request's method
+     */
+    public abstract String method();
+
+    /**
+     * Returns the duration for this request.
+     *
+     * @return this requests duration
+     */
+    public abstract Duration duration();
+
+    /**
+     * Returns this request's {@link HttpRequest.Builder#expectContinue(boolean)
+     * expect continue } setting.
+     *
+     * @return this request's expect continue setting
+     */
+    public abstract boolean expectContinue();
+
+    /**
+     * Returns this request's request {@code URI}.
+     *
+     * @return this request's URI
+     */
+    public abstract URI uri();
+
+    /**
+     * Returns the HTTP protocol version that will be requested for this
+     * {@code HttpRequest}. The corresponding {@link HttpResponse} should be
+     * queried to determine the version that was actually used.
+     *
+     * @return HTTP protocol version
+     */
+    public abstract HttpClient.Version version();
+
+    /**
+     * The (user-accessible) request headers that this request was (or will be)
+     * sent with.
+     *
+     * @return this request's HttpHeaders
+     */
+    public abstract HttpHeaders headers();
+
+
+    /**
+     * A request body handler which sends no request body.
+     *
+     * @return a BodyProcessor
+     */
+    public static BodyProcessor noBody() {
+        return new RequestProcessors.EmptyProcessor();
+    }
+
+    /**
+     * A processor which converts high level Java objects into flows of
+     * {@link java.nio.ByteBuffer}s suitable for sending as request bodies.
+     * {@code BodyProcessor}s implement {@link Flow.Publisher} which means they act as a
+     * publisher of byte buffers.
+     * <p>
+     * The HTTP client implementation subscribes to the processor in
+     * order to receive the flow of outgoing data buffers. The normal semantics
+     * of {@link Flow.Subscriber} and {@link Flow.Publisher} are implemented
+     * by the library and expected from processor implementations.
+     * Each outgoing request results in one {@code Subscriber} subscribing to the
+     * {@code Publisher} in order to provide the sequence of {@code ByteBuffer}s containing
+     * the request body. {@code ByteBuffer}s must be allocated by the processor,
+     * and must not be accessed after being handed over to the library.
+     * These subscriptions complete normally when the request is fully
+     * sent, and can be canceled or terminated early through error. If a request
+     * needs to be resent for any reason, then a new subscription is created
+     * which is expected to generate the same data as before.
+     */
+    public interface BodyProcessor extends Flow.Publisher<ByteBuffer> {
+
+        /**
+         * Returns a request body processor whose body is the given {@code String},
+         * converted using the {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8}
+         * character set.
+         *
+         * @param body the String containing the body
+         * @return a BodyProcessor
+         */
+        static BodyProcessor fromString(String body) {
+            return fromString(body, StandardCharsets.UTF_8);
+        }
+
+        /**
+         * Returns a request body processor whose body is the given {@code String}, converted
+         * using the given character set.
+         *
+         * @param s the String containing the body
+         * @param charset the character set to convert the string to bytes
+         * @return a BodyProcessor
+         */
+        static BodyProcessor fromString(String s, Charset charset) {
+            return new RequestProcessors.StringProcessor(s, charset);
+        }
+
+        /**
+         * A request body processor that reads its data from an {@link java.io.InputStream}.
+         * A {@link Supplier} of {@code InputStream} is used in case the request needs
+         * to be sent again as the content is not buffered. The {@code Supplier} may return
+         * {@code null} on subsequent attempts in which case, the request fails.
+         *
+         * @param streamSupplier a Supplier of open InputStreams
+         * @return a BodyProcessor
+         */
+        // TODO (spec): specify that the stream will be closed
+        static BodyProcessor fromInputStream(Supplier<? extends InputStream> streamSupplier) {
+            return new RequestProcessors.InputStreamProcessor(streamSupplier);
+        }
+
+        /**
+         * Returns a request body processor whose body is the given byte array.
+         *
+         * @param buf the byte array containing the body
+         * @return a BodyProcessor
+         */
+        static BodyProcessor fromByteArray(byte[] buf) {
+            return new RequestProcessors.ByteArrayProcessor(buf);
+        }
+
+        /**
+         * Returns a request body processor whose body is the content of the given byte
+         * array of {@code length} bytes starting from the specified
+         * {@code offset}.
+         *
+         * @param buf the byte array containing the body
+         * @param offset the offset of the first byte
+         * @param length the number of bytes to use
+         * @return a BodyProcessor
+         */
+        static BodyProcessor fromByteArray(byte[] buf, int offset, int length) {
+            return new RequestProcessors.ByteArrayProcessor(buf, offset, length);
+        }
+
+        /**
+         * A request body processor that takes data from the contents of a File.
+         *
+         * @param path the path to the file containing the body
+         * @return a BodyProcessor
+         * @throws java.io.FileNotFoundException if path not found
+         */
+        static BodyProcessor fromFile(Path path) throws FileNotFoundException {
+            return new RequestProcessors.FileProcessor(path);
+        }
+
+        /**
+         * A request body processor that takes data from an {@code Iterable} of byte arrays.
+         * An {@link Iterable} is provided which supplies {@link Iterator} instances.
+         * Each attempt to send the request results in one invocation of the
+         * {@code Iterable}
+         *
+         * @param iter an Iterable of byte arrays
+         * @return a BodyProcessor
+         */
+        static BodyProcessor fromByteArrays(Iterable<byte[]> iter) {
+            return new RequestProcessors.IterableProcessor(iter);
+        }
+        /**
+         * Returns the content length for this request body. May be zero
+         * if no request content being sent, greater than zero for a fixed
+         * length content, and less than zero for an unknown content length.
+         *
+         * @return the content length for this request body if known
+         */
+        long contentLength();
+
+//        /**
+//         * Returns a used {@code ByteBuffer} to this request processor. When the
+//         * HTTP implementation has finished sending the contents of a buffer,
+//         * this method is called to return it to the processor for re-use.
+//         *
+//         * @param buffer a used ByteBuffer
+//         */
+        //void returnBuffer(ByteBuffer buffer);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpRequestBuilderImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.net.URI;
+import jdk.incubator.http.HttpRequest.BodyProcessor;
+import java.time.Duration;
+import static java.util.Objects.requireNonNull;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import static jdk.incubator.http.internal.common.Utils.isValidName;
+import static jdk.incubator.http.internal.common.Utils.isValidValue;
+
+class HttpRequestBuilderImpl extends HttpRequest.Builder {
+
+    private HttpHeadersImpl userHeaders;
+    private URI uri;
+    private String method;
+    //private HttpClient.Redirect followRedirects;
+    private boolean expectContinue;
+    private HttpRequest.BodyProcessor body;
+    private HttpClient.Version version;
+    //private final HttpClientImpl client;
+    //private ProxySelector proxy;
+    private Duration duration;
+
+    public HttpRequestBuilderImpl(URI uri) {
+        //this.client = client;
+        checkURI(uri);
+        this.uri = uri;
+        this.userHeaders = new HttpHeadersImpl();
+        this.method = "GET"; // default, as per spec
+    }
+
+    public HttpRequestBuilderImpl() {
+        this.userHeaders = new HttpHeadersImpl();
+    }
+
+    @Override
+    public HttpRequestBuilderImpl uri(URI uri) {
+        requireNonNull(uri);
+        checkURI(uri);
+        this.uri = uri;
+        return this;
+    }
+
+    private static void checkURI(URI uri) {
+        String scheme = uri.getScheme().toLowerCase();
+        if (!scheme.equals("https") && !scheme.equals("http")) {
+            throw new IllegalArgumentException("invalid URI scheme");
+        }
+    }
+/*
+    @Override
+    public HttpRequestBuilderImpl followRedirects(HttpClient.Redirect follow) {
+        requireNonNull(follow);
+        this.followRedirects = follow;
+        return this;
+    }
+*/
+    @Override
+    public HttpRequestBuilderImpl header(String name, String value) {
+        checkNameAndValue(name, value);
+        userHeaders.addHeader(name, value);
+        return this;
+    }
+
+    @Override
+    public HttpRequestBuilderImpl headers(String... params) {
+        requireNonNull(params);
+        if (params.length % 2 != 0) {
+            throw new IllegalArgumentException("wrong number of parameters");
+        }
+        for (int i = 0; i < params.length; i += 2) {
+            String name  = params[i];
+            String value = params[i + 1];
+            header(name, value);
+        }
+        return this;
+    }
+
+    /*
+    @Override
+    public HttpRequestBuilderImpl proxy(ProxySelector proxy) {
+        requireNonNull(proxy);
+        this.proxy = proxy;
+        return this;
+    }
+*/
+    @Override
+    public HttpRequestBuilderImpl copy() {
+        HttpRequestBuilderImpl b = new HttpRequestBuilderImpl(this.uri);
+        b.userHeaders = this.userHeaders.deepCopy();
+        b.method = this.method;
+        //b.followRedirects = this.followRedirects;
+        b.expectContinue = this.expectContinue;
+        b.body = body;
+        b.uri = uri;
+        //b.proxy = proxy;
+        return b;
+    }
+
+    @Override
+    public HttpRequestBuilderImpl setHeader(String name, String value) {
+        checkNameAndValue(name, value);
+        userHeaders.setHeader(name, value);
+        return this;
+    }
+
+    private void checkNameAndValue(String name, String value) {
+        requireNonNull(name, "name");
+        requireNonNull(value, "value");
+        if (!isValidName(name)) {
+            throw new IllegalArgumentException("invalid header name");
+        }
+        if (!isValidValue(value)) {
+            throw new IllegalArgumentException("invalid header value");
+        }
+    }
+
+    @Override
+    public HttpRequestBuilderImpl expectContinue(boolean enable) {
+        expectContinue = enable;
+        return this;
+    }
+
+    @Override
+    public HttpRequestBuilderImpl version(HttpClient.Version version) {
+        requireNonNull(version);
+        this.version = version;
+        return this;
+    }
+
+    HttpHeadersImpl headers() {  return userHeaders; }
+
+    //HttpClientImpl client() {return client;}
+
+    URI uri() { return uri; }
+
+    String method() { return method; }
+
+    //HttpClient.Redirect followRedirects() { return followRedirects; }
+
+    //ProxySelector proxy() { return proxy; }
+
+    boolean expectContinue() { return expectContinue; }
+
+    public HttpRequest.BodyProcessor body() { return body; }
+
+    HttpClient.Version version() { return version; }
+
+    @Override
+    public HttpRequest.Builder GET() { return method("GET", null); }
+
+    @Override
+    public HttpRequest.Builder POST(BodyProcessor body) {
+        return method("POST", body);
+    }
+
+    @Override
+    public HttpRequest.Builder DELETE(BodyProcessor body) {
+        return method("DELETE", body);
+    }
+
+    @Override
+    public HttpRequest.Builder PUT(BodyProcessor body) {
+        return method("PUT", body);
+    }
+
+    @Override
+    public HttpRequest.Builder method(String method, BodyProcessor body) {
+        this.method = requireNonNull(method);
+        this.body = body;
+        return this;
+    }
+
+    @Override
+    public HttpRequest build() {
+        return new HttpRequestImpl(this);
+    }
+
+    @Override
+    public HttpRequest.Builder timeout(Duration duration) {
+        requireNonNull(duration);
+        if (duration.isNegative() || Duration.ZERO.equals(duration))
+            throw new IllegalArgumentException("Invalid duration: " + duration);
+        this.duration = duration;
+        return this;
+    }
+
+    Duration duration() { return duration; }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpRequestImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import jdk.incubator.http.internal.websocket.WebSocketRequest;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.security.AccessControlContext;
+import java.time.Duration;
+import java.util.Locale;
+import java.util.Optional;
+
+import static jdk.incubator.http.internal.common.Utils.ALLOWED_HEADERS;
+
+class HttpRequestImpl extends HttpRequest implements WebSocketRequest {
+
+    private final HttpHeaders userHeaders;
+    private final HttpHeadersImpl systemHeaders;
+    private final URI uri;
+    private InetSocketAddress authority; // only used when URI not specified
+    private final String method;
+    final BodyProcessor requestProcessor;
+    final boolean secure;
+    final boolean expectContinue;
+    private boolean isWebSocket;
+    private AccessControlContext acc;
+    private final Duration duration;
+    private final HttpClient.Version version;
+
+    /**
+     * Creates an HttpRequestImpl from the given builder.
+     */
+    public HttpRequestImpl(HttpRequestBuilderImpl builder) {
+        this.method = builder.method();
+        this.userHeaders = ImmutableHeaders.of(builder.headers().map(), ALLOWED_HEADERS);
+        this.systemHeaders = new HttpHeadersImpl();
+        this.uri = builder.uri();
+        this.expectContinue = builder.expectContinue();
+        this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
+        if (builder.body() == null) {
+            this.requestProcessor = HttpRequest.noBody();
+        } else {
+            this.requestProcessor = builder.body();
+        }
+        this.duration = builder.duration();
+        this.version = builder.version();
+    }
+
+    /**
+     * Creates an HttpRequestImpl from the given request.
+     */
+    public HttpRequestImpl(HttpRequest request) {
+        this.method = request.method();
+        this.userHeaders = request.headers();
+        if (request instanceof HttpRequestImpl) {
+            this.systemHeaders = ((HttpRequestImpl) request).systemHeaders;
+        } else {
+            this.systemHeaders = new HttpHeadersImpl();
+        }
+        this.uri = request.uri();
+        this.expectContinue = request.expectContinue();
+        this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
+        if (!request.bodyProcessor().isPresent()) {
+            this.requestProcessor = HttpRequest.noBody();
+        } else {
+            this.requestProcessor = request.bodyProcessor().get();
+        }
+        this.duration = request.duration();
+        this.version = request.version();
+    }
+
+    /** Creates a HttpRequestImpl using fields of an existing request impl. */
+    public HttpRequestImpl(URI uri,
+                           String method,
+                           HttpRequestImpl other) {
+        this.method = method == null? "GET" : method;
+        this.userHeaders = other.userHeaders;
+        this.systemHeaders = other.systemHeaders;
+        this.uri = uri;
+        this.expectContinue = other.expectContinue;
+        this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
+        this.requestProcessor = other.requestProcessor;
+        this.acc = other.acc;
+        this.duration = other.duration;
+        this.version = other.version();
+    }
+
+    /* used for creating CONNECT requests  */
+    HttpRequestImpl(String method, HttpClientImpl client,
+                    InetSocketAddress authority) {
+        this.method = method;
+        this.systemHeaders = new HttpHeadersImpl();
+        this.userHeaders = ImmutableHeaders.empty();
+        this.uri = null;
+        this.requestProcessor = HttpRequest.noBody();
+        this.authority = authority;
+        this.secure = false;
+        this.expectContinue = false;
+        this.duration = null; // block TODO: fix
+        this.version = client.version(); // TODO: ??
+    }
+
+    /**
+     * Creates a HttpRequestImpl from the given set of Headers and the associated
+     * "parent" request. Fields not taken from the headers are taken from the
+     * parent.
+     */
+    static HttpRequestImpl createPushRequest(HttpRequestImpl parent,
+                                             HttpHeadersImpl headers)
+        throws IOException
+    {
+        return new HttpRequestImpl(parent, headers);
+    }
+
+    // only used for push requests
+    private HttpRequestImpl(HttpRequestImpl parent, HttpHeadersImpl headers)
+        throws IOException
+    {
+        this.method = headers.firstValue(":method")
+                .orElseThrow(() -> new IOException("No method in Push Promise"));
+        String path = headers.firstValue(":path")
+                .orElseThrow(() -> new IOException("No path in Push Promise"));
+        String scheme = headers.firstValue(":scheme")
+                .orElseThrow(() -> new IOException("No scheme in Push Promise"));
+        String authority = headers.firstValue(":authority")
+                .orElseThrow(() -> new IOException("No authority in Push Promise"));
+        StringBuilder sb = new StringBuilder();
+        sb.append(scheme).append("://").append(authority).append(path);
+        this.uri = URI.create(sb.toString());
+
+        this.userHeaders = ImmutableHeaders.of(headers.map(), ALLOWED_HEADERS);
+        this.systemHeaders = parent.systemHeaders;
+        this.expectContinue = parent.expectContinue;
+        this.secure = parent.secure;
+        this.requestProcessor = parent.requestProcessor;
+        this.acc = parent.acc;
+        this.duration = parent.duration;
+        this.version = parent.version;
+    }
+
+    @Override
+    public String toString() {
+        return (uri == null ? "" : uri.toString()) + " " + method;
+    }
+
+    @Override
+    public HttpHeaders headers() {
+        return userHeaders;
+    }
+
+    InetSocketAddress authority() { return authority; }
+
+    void setH2Upgrade(Http2ClientImpl h2client) {
+        systemHeaders.setHeader("Connection", "Upgrade, HTTP2-Settings");
+        systemHeaders.setHeader("Upgrade", "h2c");
+        systemHeaders.setHeader("HTTP2-Settings", h2client.getSettingsString());
+    }
+
+    @Override
+    public boolean expectContinue() { return expectContinue; }
+
+    public boolean requestHttp2() {
+        return version.equals(HttpClient.Version.HTTP_2);
+    }
+
+//    AccessControlContext getAccessControlContext() { return acc; }
+
+    InetSocketAddress proxy(HttpClientImpl client) {
+        ProxySelector ps = client.proxy().orElse(null);
+        if (ps == null) {
+            ps = client.proxy().orElse(null);
+        }
+        if (ps == null || method.equalsIgnoreCase("CONNECT")) {
+            return null;
+        }
+        return (InetSocketAddress)ps.select(uri).get(0).address();
+    }
+
+    boolean secure() { return secure; }
+
+    @Override
+    public void isWebSocket(boolean is) {
+        isWebSocket = is;
+    }
+
+    boolean isWebSocket() {
+        return isWebSocket;
+    }
+
+//    /** Returns the follow-redirects setting for this request. */
+//    @Override
+//    public jdk.incubator.http.HttpClient.Redirect followRedirects() {
+//        return followRedirects;
+//    }
+
+    @Override
+    public Optional<BodyProcessor> bodyProcessor() {
+        return Optional.of(requestProcessor);
+    }
+
+    /**
+     * Returns the request method for this request. If not set explicitly,
+     * the default method for any request is "GET".
+     */
+    @Override
+    public String method() { return method; }
+
+    @Override
+    public URI uri() { return uri; }
+
+    @Override
+    public Duration duration() {
+        return duration;
+    }
+
+//    HttpClientImpl client() {
+//        return client;
+//    }
+
+    HttpHeaders getUserHeaders() { return userHeaders; }
+
+    HttpHeadersImpl getSystemHeaders() { return systemHeaders; }
+
+    @Override
+    public HttpClient.Version version() { return version; }
+
+    void addSystemHeader(String name, String value) {
+        systemHeaders.addHeader(name, value);
+    }
+
+    @Override
+    public void setSystemHeader(String name, String value) {
+        systemHeaders.setHeader(name, value);
+    }
+
+//    @Override
+//    public <T> HttpResponse<T>
+//    response(HttpResponse.BodyHandler<T> responseHandler)
+//        throws IOException, InterruptedException
+//    {
+//        if (!sent.compareAndSet(false, true)) {
+//            throw new IllegalStateException("request already sent");
+//        }
+//        MultiExchange<Void,T> mex = new MultiExchange<>(this, responseHandler);
+//        return mex.response();
+//    }
+//
+//    @Override
+//    public <T> CompletableFuture<HttpResponse<T>>
+//    responseAsync(HttpResponse.BodyHandler<T> responseHandler)
+//    {
+//        if (!sent.compareAndSet(false, true)) {
+//            throw new IllegalStateException("request already sent");
+//        }
+//        MultiExchange<Void,T> mex = new MultiExchange<>(this, responseHandler);
+//        return mex.responseAsync(null)
+//                  .thenApply((HttpResponseImpl<T> b) -> (HttpResponse<T>) b);
+//    }
+//
+//    @Override
+//    public <U, T> CompletableFuture<U>
+//    multiResponseAsync(HttpResponse.MultiProcessor<U, T> responseHandler)
+//    {
+//        if (!sent.compareAndSet(false, true)) {
+//            throw new IllegalStateException("request already sent");
+//        }
+//        MultiExchange<U,T> mex = new MultiExchange<>(this, responseHandler);
+//        return mex.multiResponseAsync();
+//    }
+
+    public InetSocketAddress getAddress(HttpClientImpl client) {
+        URI uri = uri();
+        if (uri == null) {
+            return authority();
+        }
+        int port = uri.getPort();
+        if (port == -1) {
+            if (uri.getScheme().equalsIgnoreCase("https")) {
+                port = 443;
+            } else {
+                port = 80;
+            }
+        }
+        String host = uri.getHost();
+        if (proxy(client) == null) {
+            return new InetSocketAddress(host, port);
+        } else {
+            return InetSocketAddress.createUnresolved(host, port);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponse.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import jdk.incubator.http.ResponseProcessors.MultiFile;
+import jdk.incubator.http.ResponseProcessors.MultiProcessorImpl;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Flow;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import javax.net.ssl.SSLParameters;
+
+/**
+ * Represents a response to a {@link HttpRequest}. A {@code HttpResponse} is
+ * available when the response status code and headers have been received, and
+ * typically after the response body has also been received. This depends on
+ * the response body handler provided when sending the request. In all cases,
+ * the response body handler is invoked before the body is read. This gives
+ * applications an opportunity to decide how to handle the body.
+ *
+ * <p> Methods are provided in this class for accessing the response headers,
+ * and response body.
+ * <p>
+ * <b>Response handlers and processors</b>
+ * <p>
+ * Response bodies are handled at two levels. Application code supplies a response
+ * handler ({@link BodyHandler}) which may examine the response status code
+ * and headers, and which then returns a {@link BodyProcessor} to actually read
+ * (or discard) the body and convert it into some useful Java object type. The handler
+ * can return one of the pre-defined processor types, or a custom processor, or
+ * if the body is to be discarded, it can call {@link BodyProcessor#discard(Object)
+ * BodyProcessor.discard()} and return a processor which discards the response body.
+ * Static implementations of both handlers and processors are provided in
+ * {@link BodyHandler BodyHandler} and {@link BodyProcessor BodyProcessor} respectively.
+ * In all cases, the handler functions provided are convenience implementations
+ * which ignore the supplied status code and
+ * headers and return the relevant pre-defined {@code BodyProcessor}.
+ * <p>
+ * See {@link BodyHandler} for example usage.
+ *
+ * @param <T> the response body type
+ * @since 9
+ */
+public abstract class HttpResponse<T> {
+
+    /**
+     * Creates an HttpResponse.
+     */
+    protected HttpResponse() { }
+
+    /**
+     * Returns the status code for this response.
+     *
+     * @return the response code
+     */
+    public abstract int statusCode();
+
+    /**
+     * Returns the initial {@link HttpRequest} that initiated the exchange.
+     *
+     * @return the request
+     */
+    public abstract HttpRequest request();
+
+    /**
+     * Returns the final {@link HttpRequest} that was sent on the wire for the
+     * exchange ( may, or may not, be the same as the initial request ).
+     *
+     * @return the request
+     */
+    public abstract HttpRequest finalRequest();
+
+    /**
+     * Returns the received response headers.
+     *
+     * @return the response headers
+     */
+    public abstract HttpHeaders headers();
+
+    /**
+     * Returns the received response trailers, if there are any, when they
+     * become available. For many response processor types this will be at the same
+     * time as the {@code HttpResponse} itself is available. In such cases, the
+     * returned {@code CompletableFuture} will be already completed.
+     *
+     * @return a CompletableFuture of the response trailers (may be empty)
+     */
+    public abstract CompletableFuture<HttpHeaders> trailers();
+
+    /**
+     * Returns the body. Depending on the type of {@code T}, the returned body may
+     * represent the body after it was read (such as {@code byte[]}, or
+     * {@code String}, or {@code Path}) or it may represent an object with
+     * which the body is read, such as an {@link java.io.InputStream}.
+     *
+     * @return the body
+     */
+    public abstract T body();
+
+    /**
+     * Returns the {@link javax.net.ssl.SSLParameters} in effect for this
+     * response. Returns {@code null} if this is not a HTTPS response.
+     *
+     * @return the SSLParameters associated with the response
+     */
+    public abstract SSLParameters sslParameters();
+
+    /**
+     * Returns the {@code URI} that the response was received from. This may be
+     * different from the request {@code URI} if redirection occurred.
+     *
+     * @return the URI of the response
+     */
+    public abstract URI uri();
+
+    /**
+     * Returns the HTTP protocol version that was used for this response.
+     *
+     * @return HTTP protocol version
+     */
+    public abstract HttpClient.Version version();
+
+    /**
+     * A handler for response bodies. This is a function that takes two
+     * parameters: the response status code, and the response headers,
+     * and which returns a {@link BodyProcessor}. The function is always called
+     * just before the response body is read. Its implementation may examine the
+     * status code or headers and must decide, whether to accept the response
+     * body or discard it, and if accepting it, exactly how to handle it.
+     * <p>
+     * Some pre-defined implementations which do not utilize the status code
+     * or headers (meaning the body is always accepted) are defined:
+     * <ul><li>{@link #asByteArray() }</li>
+     * <li>{@link #asByteArrayConsumer(java.util.function.Consumer)
+     * asByteArrayConsumer(Consumer)}</li>
+     * <li>{@link #asFileDownload(java.nio.file.Path,OpenOption...)
+     * asFileDownload(Path,OpenOption...)}</li>
+     * <li>{@link #discard(Object) }</li>
+     * <li>{@link #asString(java.nio.charset.Charset)
+     * asString(Charset)}</li></ul>
+     * <p>
+     * These implementations return the equivalent {@link BodyProcessor}.
+     * Alternatively, the handler can be used to examine the status code
+     * or headers and return different body processors as appropriate.
+     * <p>
+     * <b>Examples of handler usage</b>
+     * <p>
+     * The first example uses one of the predefined handler functions which
+     * ignore the response headers and status, and always process the response
+     * body in the same way.
+     * <pre>
+     * {@code
+     *      HttpResponse<Path> resp = HttpRequest
+     *              .create(URI.create("http://www.foo.com"))
+     *              .GET()
+     *              .response(BodyHandler.asFile(Paths.get("/tmp/f")));
+     * }
+     * </pre>
+     * Note, that even though these pre-defined handlers ignore the status code
+     * and headers, this information is still accessible from the {@code HttpResponse}
+     * when it is returned.
+     * <p>
+     * In the second example, the function returns a different processor depending
+     * on the status code.
+     * <pre>
+     * {@code
+     *      HttpResponse<Path> resp1 = HttpRequest
+     *              .create(URI.create("http://www.foo.com"))
+     *              .GET()
+     *              .response(
+     *                  (status, headers) -> status == 200
+     *                      ? BodyProcessor.asFile(Paths.get("/tmp/f"))
+     *                      : BodyProcessor.discard(Paths.get("/NULL")));
+     * }
+     * </pre>
+     *
+     * @param <T> the response body type.
+     */
+    @FunctionalInterface
+    public interface BodyHandler<T> {
+
+        /**
+         * Return a {@link BodyProcessor BodyProcessor} considering the given response status
+         * code and headers. This method is always called before the body is read
+         * and its implementation can decide to keep the body and store it somewhere
+         * or else discard it, by  returning the {@code BodyProcessor} returned
+         * from {@link BodyProcessor#discard(java.lang.Object) discard()}.
+         *
+         * @param statusCode the HTTP status code received
+         * @param responseHeaders the response headers received
+         * @return
+         */
+        public BodyProcessor<T> apply(int statusCode, HttpHeaders responseHeaders);
+
+        /**
+         * Returns a response body handler which discards the response body and
+         * uses the given value as a replacement for it.
+         *
+         * @param <U> the response body type
+         * @param value the value of U to return as the body
+         * @return
+         */
+        public static <U> BodyHandler<U> discard(U value) {
+            return (status, headers) -> BodyProcessor.discard(value);
+        }
+
+        /**
+         * Returns a {@code BodyHandler<String>} that returns a
+         * {@link BodyProcessor BodyProcessor}{@code <String>} obtained from
+         * {@link BodyProcessor#asString(java.nio.charset.Charset)
+         * BodyProcessor.asString(Charset)}. If a charset is provided, the
+         * body is decoded using it. If charset is {@code null} then the processor
+         * tries to determine the character set from the {@code Content-encoding}
+         * header. If that charset is not supported then
+         * {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} is used.
+         *
+         * @param charset the name of the charset to interpret the body as. If
+         * {@code null} then charset determined from Content-encoding header
+         * @return a response handler
+         */
+        public static BodyHandler<String> asString(Charset charset) {
+            return (status, headers) -> {
+                if (charset != null) {
+                    return BodyProcessor.asString(charset);
+                }
+                return BodyProcessor.asString(charsetFrom(headers));
+            };
+        }
+
+        /**
+         * Get the Charset from the Content-encoding header. Defaults to
+         * UTF_8
+         */
+        private static Charset charsetFrom(HttpHeaders headers) {
+            String encoding = headers.firstValue("Content-encoding")
+                    .orElse("UTF_8");
+            try {
+                return Charset.forName(encoding);
+            } catch (IllegalArgumentException e) {
+                return StandardCharsets.UTF_8;
+            }
+        }
+
+        /**
+         * Returns a {@code BodyHandler<Path>} that returns a
+         * {@link BodyProcessor BodyProcessor}{@code <Path>} obtained from
+         * {@link BodyProcessor#asFile(Path) BodyProcessor.asFile(Path)}.
+         * <p>
+         * When the {@code HttpResponse} object is returned, the body has been completely
+         * written to the file, and {@link #body()} returns a reference to its
+         * {@link Path}.
+         *
+         * @param file the file to store the body in
+         * @return a response handler
+         */
+        public static BodyHandler<Path> asFile(Path file) {
+            return (status, headers) -> BodyProcessor.asFile(file);
+        }
+
+        /**
+         * Returns a {@code BodyHandler<Path>} that returns a
+         * {@link BodyProcessor BodyProcessor}&lt;{@link Path}&gt;
+         * where the download directory is specified, but the filename is
+         * obtained from the {@code Content-Disposition} response header. The
+         * {@code Content-Disposition} header must specify the <i>attachment</i> type
+         * and must also contain a
+         * <i>filename</i> parameter. If the filename specifies multiple path
+         * components only the final component is used as the filename (with the
+         * given directory name). When the {@code HttpResponse} object is
+         * returned, the body has been completely written to the file and {@link
+         * #body()} returns a {@code Path} object for the file. The returned {@code Path} is the
+         * combination of the supplied directory name and the file name supplied
+         * by the server. If the destination directory does not exist or cannot
+         * be written to, then the response will fail with an {@link IOException}.
+         *
+         * @param directory the directory to store the file in
+         * @param openOptions open options
+         * @return a response handler
+         */
+        public static BodyHandler<Path> asFileDownload(Path directory, OpenOption... openOptions) {
+            return (status, headers) -> {
+                String dispoHeader = headers.firstValue("Content-Disposition")
+                        .orElseThrow(() -> unchecked(new IOException("No Content-Disposition")));
+                if (!dispoHeader.startsWith("attachment;")) {
+                    throw unchecked(new IOException("Unknown Content-Disposition type"));
+                }
+                int n = dispoHeader.indexOf("filename=");
+                if (n == -1) {
+                    throw unchecked(new IOException("Bad Content-Disposition type"));
+                }
+                int lastsemi = dispoHeader.lastIndexOf(';');
+                String disposition;
+                if (lastsemi < n) {
+                    disposition = dispoHeader.substring(n + 9);
+                } else {
+                    disposition = dispoHeader.substring(n + 9, lastsemi);
+                }
+                Path file = Paths.get(directory.toString(), disposition);
+                return BodyProcessor.asFile(file, openOptions);
+            };
+        }
+
+        private static UncheckedIOException unchecked(IOException e) {
+            return new UncheckedIOException(e);
+        }
+
+        /**
+         * Returns a {@code BodyHandler<Path>} that returns a
+         * {@link BodyProcessor BodyProcessor}{@code <Path>} obtained from
+         * {@link BodyProcessor#asFile(java.nio.file.Path, java.nio.file.OpenOption...)
+         * BodyProcessor.asFile(Path,OpenOption...)}.
+         * <p>
+         * When the {@code HttpResponse} object is returned, the body has been completely
+         * written to the file, and {@link #body()} returns a reference to its
+         * {@link Path}.
+         *
+         * @param file the filename to store the body in
+         * @param openOptions any options to use when opening/creating the file
+         * @return a response handler
+         */
+        public static BodyHandler<Path> asFile(Path file, OpenOption... openOptions) {
+            return (status, headers) -> BodyProcessor.asFile(file, openOptions);
+        }
+
+        /**
+         * Returns a {@code BodyHandler<Void>} that returns a
+         * {@link BodyProcessor BodyProcessor}{@code <Void>} obtained from
+         * {@link BodyProcessor#asByteArrayConsumer(java.util.function.Consumer)
+         * BodyProcessor.asByteArrayConsumer(Consumer)}.
+         * <p>
+         * When the {@code HttpResponse} object is returned, the body has been completely
+         * written to the consumer.
+         *
+         * @param consumer a Consumer to accept the response body
+         * @return a a response handler
+         */
+        public static BodyHandler<Void> asByteArrayConsumer(Consumer<Optional<byte[]>> consumer) {
+            return (status, headers) -> BodyProcessor.asByteArrayConsumer(consumer);
+        }
+
+        /**
+         * Returns a {@code BodyHandler<byte[]>} that returns a
+         * {@link BodyProcessor BodyProcessor}&lt;{@code byte[]}&gt; obtained
+         * from {@link BodyProcessor#asByteArray() BodyProcessor.asByteArray()}.
+         * <p>
+         * When the {@code HttpResponse} object is returned, the body has been completely
+         * written to the byte array.
+         *
+         * @return a response handler
+         */
+        public static BodyHandler<byte[]> asByteArray() {
+            return (status, headers) -> BodyProcessor.asByteArray();
+        }
+
+        /**
+         * Returns a {@code BodyHandler<String>} that returns a
+         * {@link BodyProcessor BodyProcessor}{@code <String>} obtained from
+         * {@link BodyProcessor#asString(java.nio.charset.Charset)
+         * BodyProcessor.asString(Charset)}. The body is
+         * decoded using the character set specified in
+         * the {@code Content-encoding} response header. If there is no such
+         * header, or the character set is not supported, then
+         * {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} is used.
+         * <p>
+         * When the {@code HttpResponse} object is returned, the body has been completely
+         * written to the string.
+         *
+         * @return a response handler
+         */
+        public static BodyHandler<String> asString() {
+            return (status, headers) -> BodyProcessor.asString(charsetFrom(headers));
+        }
+    }
+
+    /**
+     * A processor for response bodies. The object acts as a
+     * {@link Flow.Subscriber}&lt;{@link ByteBuffer}&gt; to the HTTP client implementation
+     * which publishes ByteBuffers containing the response body. The processor
+     * converts the incoming buffers of data to some user-defined object type {@code T}.
+     * <p>
+     * The {@link #getBody()} method returns a {@link CompletionStage}{@code <T>}
+     * that provides the response body object. The {@code CompletionStage} must
+     * be obtainable at any time. When it completes depends on the nature
+     * of type {@code T}. In many cases, when {@code T} represents the entire body after being
+     * read then it completes after the body has been read. If {@code T} is a streaming
+     * type such as {@link java.io.InputStream} then it completes before the
+     * body has been read, because the calling code uses it to consume the data.
+     *
+     * @param <T> the response body type
+     */
+    public interface BodyProcessor<T>
+            extends Flow.Subscriber<ByteBuffer> {
+
+        /**
+         * Returns a {@code CompletionStage} which when completed will return the
+         * response body object.
+         *
+         * @return a CompletionStage for the response body
+         */
+        public CompletionStage<T> getBody();
+
+        /**
+         * Returns a body processor which stores the response body as a {@code
+         * String} converted using the given {@code Charset}.
+         * <p>
+         * The {@link HttpResponse} using this processor is available after the
+         * entire response has been read.
+         *
+         * @param charset the character set to convert the String with
+         * @return a body processor
+         */
+        public static BodyProcessor<String> asString(Charset charset) {
+            return new ResponseProcessors.ByteArrayProcessor<>(
+                    bytes -> new String(bytes, charset)
+            );
+        }
+
+        /**
+         * Returns a {@code BodyProcessor} which stores the response body as a
+         * byte array.
+         * <p>
+         * The {@link HttpResponse} using this processor is available after the
+         * entire response has been read.
+         *
+         * @return a body processor
+         */
+        public static BodyProcessor<byte[]> asByteArray() {
+            return new ResponseProcessors.ByteArrayProcessor<>(
+                    Function.identity() // no conversion
+            );
+        }
+
+        /**
+         * Returns a {@code BodyProcessor} which stores the response body in a
+         * file opened with the given options and name. The file will be opened
+         * with the given options using
+         * {@link java.nio.channels.FileChannel#open(java.nio.file.Path,java.nio.file.OpenOption...)
+         * FileChannel.open} just before the body is read. Any exception thrown will be returned
+         * or thrown from {@link HttpClient#send(jdk.incubator.http.HttpRequest,
+         * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::send}
+         * or {@link HttpClient#sendAsync(jdk.incubator.http.HttpRequest,
+         * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::sendAsync}
+         * as appropriate.
+         * <p>
+         * The {@link HttpResponse} using this processor is available after the
+         * entire response has been read.
+         *
+         * @param file the file to store the body in
+         * @param openOptions the list of options to open the file with
+         * @return a body processor
+         */
+        public static BodyProcessor<Path> asFile(Path file, OpenOption... openOptions) {
+            return new ResponseProcessors.PathProcessor(file, openOptions);
+        }
+
+        /**
+         * Returns a {@code BodyProcessor} which provides the incoming body
+         * data to the provided Consumer of {@code Optional<byte[]>}. Each
+         * call to {@link Consumer#accept(java.lang.Object) Consumer.accept()}
+         * will contain a non empty {@code Optional}, except for the final invocation after
+         * all body data has been read, when the {@code Optional} will be empty.
+         * <p>
+         * The {@link HttpResponse} using this processor is available after the
+         * entire response has been read.
+         *
+         * @param consumer a Consumer of byte arrays
+         * @return a BodyProcessor
+         */
+        public static BodyProcessor<Void> asByteArrayConsumer(Consumer<Optional<byte[]>> consumer) {
+            return new ResponseProcessors.ConsumerProcessor(consumer);
+        }
+
+        /**
+         * Returns a {@code BodyProcessor} which stores the response body in a
+         * file opened with the given name. Has the same effect as calling
+         * {@link #asFile(java.nio.file.Path, java.nio.file.OpenOption...) asFile}
+         * with the standard open options {@code CREATE} and {@code WRITE}
+         * <p>
+         * The {@link HttpResponse} using this processor is available after the
+         * entire response has been read.
+         *
+         * @param file the file to store the body in
+         * @return a body processor
+         */
+        public static BodyProcessor<Path> asFile(Path file) {
+            return new ResponseProcessors.PathProcessor(
+                    file,
+                    StandardOpenOption.CREATE, StandardOpenOption.WRITE);
+        }
+
+        /**
+         * Returns a response processor which discards the response body. The
+         * supplied value is the value that will be returned from
+         * {@link HttpResponse#body()}.
+         *
+         * @param <U> The type of the response body
+         * @param value the value to return from HttpResponse.body()
+         * @return a {@code BodyProcessor}
+         */
+        public static <U> BodyProcessor<U> discard(U value) {
+            return new ResponseProcessors.NullProcessor<>(Optional.ofNullable(value));
+        }
+    }
+
+    /**
+     * A response processor for a HTTP/2 multi response. A multi response
+     * comprises a main response, and zero or more additional responses. Each
+     * additional response is sent by the server in response to requests that
+     * the server also generates. Additional responses are typically resources
+     * that the server expects the client will need which are related to the
+     * initial request.
+     * <p>
+     * Note. Instead of implementing this interface, applications should consider
+     * first using the mechanism (built on this interface) provided by
+     * {@link MultiProcessor#asMap(java.util.function.Function, boolean)
+     * MultiProcessor.asMap()} which is a slightly simplified, but
+     * general purpose interface.
+     * <p>
+     * The server generated requests are also known as <i>push promises</i>.
+     * The server is permitted to send any number of these requests up to the
+     * point where the main response is fully received. Therefore, after
+     * completion of the main response, the final number of additional
+     * responses is known. Additional responses may be canceled, but given that
+     * the server does not wait for any acknowledgment before sending the
+     * response, this must be done quickly to avoid unnecessary data transmission.
+     *
+     * <p> {@code MultiProcessor}s are parameterized with a type {@code U} which
+     * represents some meaningful aggregate of the responses received. This
+     * would typically be a collection of response or response body objects.
+     *
+     * @param <U> a type representing the aggregated results
+     * @param <T> a type representing all of the response bodies
+     *
+     * @since 9
+     */
+    public interface MultiProcessor<U,T> {
+        /**
+         * Called for the main request and each push promise that is received.
+         * The first call will always be for the main request that was sent
+         * by the caller. This {@link HttpRequest} parameter
+         * represents the initial request or subsequent PUSH_PROMISE. The
+         * implementation must return an {@code Optional} of {@link BodyHandler} for
+         * the response body. Different handlers (of the same type) can be returned
+         * for different pushes within the same multi send. If no handler
+         * (an empty {@code Optional}) is returned, then the push will be canceled. It is
+         * an error to not return a valid {@code BodyHandler} for the initial (main) request.
+         *
+         * @param request the main request or subsequent push promise
+         *
+         * @return an optional body handler
+         */
+        Optional<BodyHandler<T>> onRequest(HttpRequest request);
+
+        /**
+         * Called for each response received. For each request either one of
+         * onResponse() or onError() is guaranteed to be called, but not both.
+         *
+         * [Note] The reason for switching to this callback interface rather
+         * than using CompletableFutures supplied to onRequest() is that there
+         * is a subtle interaction between those CFs and the CF returned from
+         * completion() (or when onComplete() was called formerly). The completion()
+         * CF will not complete until after all of the work done by the onResponse()
+         * calls is done. Whereas if you just create CF's dependent on a supplied
+         * CF (to onRequest()) then the implementation has no visibility of the
+         * dependent CFs and can't guarantee to call onComplete() (or complete
+         * the completion() CF) after the dependent CFs complete.
+         *
+         * @param response the response received
+         */
+        void onResponse(HttpResponse<T> response);
+
+        /**
+         * Called if an error occurs receiving a response. For each request
+         * either one of onResponse() or onError() is guaranteed to be called,
+         * but not both.
+         *
+         * @param request
+         * @param t the Throwable that caused the error
+         */
+        void onError(HttpRequest request, Throwable t);
+
+        /**
+         * Returns a {@link java.util.concurrent.CompletableFuture}{@code <U>}
+         * which completes when the aggregate result object itself is available.
+         * It is expected that the returned {@code CompletableFuture} will depend
+         * on one of the given {@code CompletableFuture<Void}s which themselves complete
+         * after all individual responses associated with the multi response
+         * have completed, or after all push promises have been received.
+         * <p>
+         * @implNote Implementations might follow the pattern shown below
+         * <pre>
+         * {@code
+         *      CompletableFuture<U> completion(
+         *              CompletableFuture<Void> onComplete,
+         *              CompletableFuture<Void> onFinalPushPromise)
+         *      {
+         *          return onComplete.thenApply((v) -> {
+         *              U u = ... instantiate and populate a U instance
+         *              return u;
+         *          });
+         *      }
+         * }
+         * </pre>
+         * <p>
+         *
+         * @param onComplete a CompletableFuture which completes after all
+         * responses have been received relating to this multi request.
+         *
+         * @param onFinalPushPromise CompletableFuture which completes after all
+         * push promises have been received.
+         *
+         * @return the aggregate CF response object
+         */
+        CompletableFuture<U> completion(CompletableFuture<Void> onComplete,
+                CompletableFuture<Void> onFinalPushPromise);
+
+        /**
+         * Returns a general purpose handler for multi responses. The aggregated
+         * result object produced by this handler is a
+         * {@code Map<HttpRequest,CompletableFuture<HttpResponse<V>>>}. Each
+         * request (both the original user generated request and each server
+         * generated push promise) is returned as a key of the map. The value
+         * corresponding to each key is a
+         * {@code CompletableFuture<HttpResponse<V>>}.
+         * <p>
+         * There are two ways to use these handlers, depending on the value of
+         * the <i>completion</I> parameter. If completion is true, then the
+         * aggregated result will be available after all responses have
+         * themselves completed. If <i>completion</i> is false, then the
+         * aggregated result will be available immediately after the last push
+         * promise was received. In the former case, this implies that all the
+         * CompletableFutures in the map values will have completed. In the
+         * latter case, they may or may not have completed yet.
+         * <p>
+         * The simplest way to use these handlers is to set completion to
+         * {@code true}, and then all (results) values in the Map will be
+         * accessible without blocking.
+         * <p>
+         * See {@link #asMap(java.util.function.Function, boolean)
+         * }
+         * for a code sample of using this interface.
+         *
+         * @param <V> the body type used for all responses
+         * @param pushHandler a function invoked for each request or push
+         * promise
+         * @param completion {@code true} if the aggregate CompletableFuture
+         * completes after all responses have been received, or {@code false}
+         * after all push promises received.
+         *
+         * @return a MultiProcessor
+         */
+        public static <V> MultiProcessor<MultiMapResult<V>,V> asMap(
+            Function<HttpRequest, Optional<HttpResponse.BodyHandler<V>>> pushHandler,
+                boolean completion) {
+
+            return new MultiProcessorImpl<V>(pushHandler, completion);
+        }
+
+        /**
+         * Returns a general purpose handler for multi responses. This is a
+         * convenience method which invokes {@link #asMap(java.util.function.Function,boolean)
+         * asMap(Function, true)} meaning that the aggregate result
+         * object completes after all responses have been received.
+         * <p>
+         * <b>Example usage:</b>
+         * <br>
+         * <pre>
+         * {@code
+         *          HttpRequest request = HttpRequest.newBuilder()
+         *                  .uri(URI.create("https://www.foo.com/"))
+         *                  .GET()
+         *                  .build();
+         *
+         *          HttpClient client = HttpClient.newHttpClient();
+         *
+         *          Map<HttpRequest,CompletableFuture<HttpResponse<String>>> results = client
+         *              .sendAsync(request, MultiProcessor.asMap(
+         *                  (req) -> Optional.of(HttpResponse.BodyHandler.asString())))
+         *              .join();
+         * }</pre>
+         * <p>
+         * The lambda in this example is the simplest possible implementation,
+         * where neither the incoming requests are examined, nor the response
+         * headers, and every push that the server sends is accepted. When the
+         * join() call returns, all {@code HttpResponse}s and their associated
+         * body objects are available.
+         *
+         * @param <V>
+         * @param pushHandler a function invoked for each request or push
+         * promise
+         * @return a MultiProcessor
+         */
+        public static <V> MultiProcessor<MultiMapResult<V>,V> asMap(
+            Function<HttpRequest, Optional<HttpResponse.BodyHandler<V>>> pushHandler) {
+
+            return asMap(pushHandler, true);
+        }
+
+        /**
+         * Returns a {@code MultiProcessor} which writes the response bodies to
+         * files under a given root directory and which returns an aggregate
+         * response map that is a {@code Map<HttpRequest, HttpResponse<Path>>}.
+         * The keyset of the {@code Map} represents the original request and any
+         * additional requests generated by the server. The values are the
+         * responses containing the paths of the destination files. Each file
+         * uses the URI path of the request relative to the destination parent
+         * directorycprovided.
+         *
+         * <p>
+         * All incoming additional requests (push promises) are accepted by this
+         * multi response processor. Errors are effectively ignored and any
+         * failed responses are simply omitted from the result {@code Map}.
+         * Other implementations of {@code MultiProcessor} may handle these
+         * situations.
+         *
+         * <p>
+         * <b>Example usage</b>
+         * <pre>
+         * {@code
+         *    HttpClient client = ..
+         *    HttpRequest request = HttpRequest
+         *               .create(new URI("https://www.foo.com/"))
+         *               .version(Version.HTTP2)
+         *               .GET();
+         *
+         *    Map<HttpRequest, HttpResponse<Path>>> map = client
+         *               .sendAsync(HttpResponse.MultiProcessor.multiFile("/usr/destination"))
+         *               .join();
+         *
+         * }
+         * </pre>
+         * TEMPORARILY REMOVING THIS FROM API. MIGHT NOT BE NEEDED.
+         *
+         * @param destination the destination parent directory of all response
+         * bodies
+         * @return a MultiProcessor
+         */
+        private static MultiProcessor<MultiMapResult<Path>,Path> multiFile(Path destination) {
+            MultiFile mf = new MultiFile(destination);
+            return new MultiProcessorImpl<Path>(mf::handlePush, true);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponseImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import javax.net.ssl.SSLParameters;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.websocket.RawChannel;
+
+/**
+ * The implementation class for HttpResponse
+ */
+class HttpResponseImpl<T> extends HttpResponse<T> implements RawChannel.Provider {
+
+    final int responseCode;
+    final Exchange<T> exchange;
+    final HttpRequest initialRequest;
+    final HttpRequestImpl finalRequest;
+    final HttpHeaders headers;
+    //final HttpHeaders trailers;
+    final SSLParameters sslParameters;
+    final URI uri;
+    final HttpClient.Version version;
+    //final AccessControlContext acc;
+    RawChannel rawchan;
+    final HttpConnection connection;
+    final Stream<T> stream;
+    final T body;
+
+    public HttpResponseImpl(HttpRequest initialRequest,
+                            Response response,
+                            T body, Exchange<T> exch) {
+        this.responseCode = response.statusCode();
+        this.exchange = exch;
+        this.initialRequest = initialRequest;
+        this.finalRequest = exchange.request();
+        this.headers = response.headers();
+        //this.trailers = trailers;
+        this.sslParameters = exch.client().sslParameters().orElse(null);
+        this.uri = finalRequest.uri();
+        this.version = response.version();
+        this.connection = exch.exchImpl.connection();
+        this.stream = null;
+        this.body = body;
+    }
+
+    // A response to a PUSH_PROMISE
+    public HttpResponseImpl(Response response,
+                            HttpRequestImpl pushRequest,
+                            ImmutableHeaders headers,
+                            Stream<T> stream,
+                            SSLParameters sslParameters,
+                            T body) {
+        this.responseCode = response.statusCode();
+        this.exchange = null;
+        this.initialRequest = null; // ## fix this
+        this.finalRequest = pushRequest;
+        this.headers = headers;
+        //this.trailers = null;
+        this.sslParameters = sslParameters;
+        this.uri = finalRequest.uri(); // TODO: take from headers
+        this.version = HttpClient.Version.HTTP_2;
+        this.connection = stream.connection();
+        this.stream = stream;
+        this.body = body;
+    }
+
+    private ExchangeImpl<?> exchangeImpl() {
+        return exchange != null ? exchange.exchImpl : stream;
+    }
+
+    @Override
+    public int statusCode() {
+        return responseCode;
+    }
+
+    @Override
+    public HttpRequest request() {
+        return initialRequest;
+    }
+
+    @Override
+    public HttpRequest finalRequest() {
+        return finalRequest;
+    }
+
+    @Override
+    public HttpHeaders headers() {
+        return headers;
+    }
+
+    @Override
+    public T body() {
+        return body;
+    }
+
+    @Override
+    public SSLParameters sslParameters() {
+        return sslParameters;
+    }
+
+    @Override
+    public URI uri() {
+        return uri;
+    }
+
+    @Override
+    public HttpClient.Version version() {
+        return version;
+    }
+    // keepalive flag determines whether connection is closed or kept alive
+    // by reading/skipping data
+
+    /**
+     * Returns a RawChannel that may be used for WebSocket protocol.
+     * @implNote This implementation does not support RawChannel over
+     *           HTTP/2 connections.
+     * @return a RawChannel that may be used for WebSocket protocol.
+     * @throws UnsupportedOperationException if getting a RawChannel over
+     *         this connection is not supported.
+     * @throws IOException if an I/O exception occurs while retrieving
+     *         the channel.
+     */
+    @Override
+    public synchronized RawChannel rawChannel() throws IOException {
+        if (rawchan == null) {
+            ExchangeImpl<?> exchImpl = exchangeImpl();
+            if (!(exchImpl instanceof Http1Exchange)) {
+                // RawChannel is only used for WebSocket - and WebSocket
+                // is not supported over HTTP/2 yet, so we should not come
+                // here. Getting a RawChannel over HTTP/2 might be supported
+                // in the future, but it would entail retrieving any left over
+                // bytes that might have been read but not consumed by the
+                // HTTP/2 connection.
+                throw new UnsupportedOperationException("RawChannel is not supported over HTTP/2");
+            }
+            // Http1Exchange may have some remaining bytes in its
+            // internal buffer.
+            final ByteBuffer remaining =((Http1Exchange<?>)exchImpl).getBuffer();
+            rawchan = new RawChannelImpl(exchange.client(), connection, remaining);
+        }
+        return rawchan;
+    }
+
+    @Override
+    public CompletableFuture<HttpHeaders> trailers() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    static void logResponse(Response r) {
+        if (!Log.requests()) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        String method = r.request().method();
+        URI uri = r.request().uri();
+        String uristring = uri == null ? "" : uri.toString();
+        sb.append('(')
+                .append(method)
+                .append(" ")
+                .append(uristring)
+                .append(") ")
+                .append(r.statusCode());
+        Log.logResponse(sb.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpTimeoutException.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a response is not received within a specified time period.
+ */
+public class HttpTimeoutException extends IOException {
+
+    private static final long serialVersionUID = 981344271622632951L;
+
+    public HttpTimeoutException(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ImmutableHeaders.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.OptionalLong;
+import java.util.TreeMap;
+import java.util.function.Predicate;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableMap;
+import static java.util.Objects.requireNonNull;
+
+final class ImmutableHeaders implements HttpHeaders {
+
+    private final Map<String, List<String>> map;
+
+    public static ImmutableHeaders empty() {
+        return of(emptyMap());
+    }
+
+    public static ImmutableHeaders of(Map<String, List<String>> src) {
+        return of(src, x -> true);
+    }
+
+    public static ImmutableHeaders of(Map<String, List<String>> src,
+                                      Predicate<? super String> keyAllowed) {
+        requireNonNull(src, "src");
+        requireNonNull(keyAllowed, "keyAllowed");
+        return new ImmutableHeaders(src, keyAllowed);
+    }
+
+    private ImmutableHeaders(Map<String, List<String>> src,
+                             Predicate<? super String> keyAllowed) {
+        Map<String, List<String>> m = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+        src.entrySet().stream()
+                .filter(e -> keyAllowed.test(e.getKey()))
+                .forEach(e ->
+                        {
+                            List<String> values = new ArrayList<>(e.getValue());
+                            m.put(e.getKey(), unmodifiableList(values));
+                        }
+                );
+        this.map = unmodifiableMap(m);
+    }
+
+    @Override
+    public Optional<String> firstValue(String name) {
+        return allValues(name).stream().findFirst();
+    }
+
+    @Override
+    public OptionalLong firstValueAsLong(String name) {
+        return allValues(name).stream().mapToLong(Long::valueOf).findFirst();
+    }
+
+    @Override
+    public List<String> allValues(String name) {
+        requireNonNull(name);
+        List<String> values = map.get(name);
+        // Making unmodifiable list out of empty in order to make a list which
+        // throws UOE unconditionally
+        return values != null ? values : unmodifiableList(emptyList());
+    }
+
+    @Override
+    public Map<String, List<String>> map() {
+        return map;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiExchange.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.List;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.ExecutionException;
+import java.util.function.BiFunction;
+import java.util.concurrent.Executor;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Pair;
+import jdk.incubator.http.internal.common.Utils;
+import static jdk.incubator.http.internal.common.Pair.pair;
+
+/**
+ * Encapsulates multiple Exchanges belonging to one HttpRequestImpl.
+ * - manages filters
+ * - retries due to filters.
+ * - I/O errors and most other exceptions get returned directly to user
+ *
+ * Creates a new Exchange for each request/response interaction
+ */
+class MultiExchange<U,T> {
+
+    private final HttpRequest userRequest; // the user request
+    private final HttpRequestImpl request; // a copy of the user request
+    final AccessControlContext acc;
+    final HttpClientImpl client;
+    final HttpResponse.BodyHandler<T> responseHandler;
+    final ExecutorWrapper execWrapper;
+    final Executor executor;
+    final HttpResponse.MultiProcessor<U,T> multiResponseHandler;
+    HttpRequestImpl currentreq; // used for async only
+    Exchange<T> exchange; // the current exchange
+    Exchange<T> previous;
+    int attempts;
+    // Maximum number of times a request will be retried/redirected
+    // for any reason
+
+    static final int DEFAULT_MAX_ATTEMPTS = 5;
+    static final int max_attempts = Utils.getIntegerNetProperty(
+            "jdk.httpclient.redirects.retrylimit", DEFAULT_MAX_ATTEMPTS
+    );
+
+    private final List<HeaderFilter> filters;
+    TimedEvent timedEvent;
+    volatile boolean cancelled;
+    final PushGroup<U,T> pushGroup;
+
+    /**
+     * Filter fields. These are attached as required by filters
+     * and only used by the filter implementations. This could be
+     * generalised into Objects that are passed explicitly to the filters
+     * (one per MultiExchange object, and one per Exchange object possibly)
+     */
+    volatile AuthenticationFilter.AuthInfo serverauth, proxyauth;
+    // RedirectHandler
+    volatile int numberOfRedirects = 0;
+
+    /**
+     * MultiExchange with one final response.
+     */
+    MultiExchange(HttpRequest req,
+                  HttpClientImpl client,
+                  HttpResponse.BodyHandler<T> responseHandler) {
+        this.previous = null;
+        this.userRequest = req;
+        this.request = new HttpRequestImpl(req);
+        this.currentreq = request;
+        this.attempts = 0;
+        this.client = client;
+        this.filters = client.filterChain();
+        if (System.getSecurityManager() != null) {
+            this.acc = AccessController.getContext();
+        } else {
+            this.acc = null;
+        }
+        this.execWrapper = new ExecutorWrapper(client.executor(), acc);
+        this.executor = execWrapper.executor();
+        this.responseHandler = responseHandler;
+        this.exchange = new Exchange<>(request, this);
+        this.multiResponseHandler = null;
+        this.pushGroup = null;
+    }
+
+    /**
+     * MultiExchange with multiple responses (HTTP/2 server pushes).
+     */
+    MultiExchange(HttpRequest req,
+                  HttpClientImpl client,
+                  HttpResponse.MultiProcessor<U, T> multiResponseHandler) {
+        this.previous = null;
+        this.userRequest = req;
+        this.request = new HttpRequestImpl(req);
+        this.currentreq = request;
+        this.attempts = 0;
+        this.client = client;
+        this.filters = client.filterChain();
+        if (System.getSecurityManager() != null) {
+            this.acc = AccessController.getContext();
+        } else {
+            this.acc = null;
+        }
+        this.execWrapper = new ExecutorWrapper(client.executor(), acc);
+        this.executor = execWrapper.executor();
+        this.multiResponseHandler = multiResponseHandler;
+        this.pushGroup = new PushGroup<>(multiResponseHandler, request);
+        this.exchange = new Exchange<>(request, this);
+        this.responseHandler = pushGroup.mainResponseHandler();
+    }
+
+    public HttpResponseImpl<T> response() throws IOException, InterruptedException {
+        HttpRequestImpl r = request;
+        if (r.duration() != null) {
+            timedEvent = new TimedEvent(r.duration());
+            client.registerTimer(timedEvent);
+        }
+        while (attempts < max_attempts) {
+            try {
+                attempts++;
+                Exchange<T> currExchange = getExchange();
+                requestFilters(r);
+                Response response = currExchange.response();
+                Pair<Response, HttpRequestImpl> filterResult = responseFilters(response);
+                HttpRequestImpl newreq = filterResult.second;
+                if (newreq == null) {
+                    if (attempts > 1) {
+                        Log.logError("Succeeded on attempt: " + attempts);
+                    }
+                    T body = currExchange.readBody(responseHandler);
+                    cancelTimer();
+                    return new HttpResponseImpl<>(userRequest, response, body, currExchange);
+                }
+                //response.body(HttpResponse.ignoreBody());
+                setExchange(new Exchange<>(newreq, this, acc));
+                r = newreq;
+            } catch (IOException e) {
+                if (cancelled) {
+                    throw new HttpTimeoutException("Request timed out");
+                }
+                throw e;
+            }
+        }
+        cancelTimer();
+        throw new IOException("Retry limit exceeded");
+    }
+
+    CompletableFuture<Void> multiCompletionCF() {
+        return pushGroup.groupResult();
+    }
+
+    private synchronized Exchange<T> getExchange() {
+        return exchange;
+    }
+
+    HttpClientImpl client() {
+        return client;
+    }
+
+    HttpClient.Redirect followRedirects() {
+        return client.followRedirects();
+    }
+
+    HttpClient.Version version() {
+        return client.version();
+    }
+
+    private synchronized void setExchange(Exchange<T> exchange) {
+        this.exchange = exchange;
+    }
+
+    private void cancelTimer() {
+        if (timedEvent != null) {
+            client.cancelTimer(timedEvent);
+        }
+    }
+
+    private void requestFilters(HttpRequestImpl r) throws IOException {
+        Log.logTrace("Applying request filters");
+        for (HeaderFilter filter : filters) {
+            Log.logTrace("Applying {0}", filter);
+            filter.request(r, this);
+        }
+        Log.logTrace("All filters applied");
+    }
+
+    // Filters are assumed to be non-blocking so the async
+    // versions of these methods just call the blocking ones
+
+    private CompletableFuture<Void> requestFiltersAsync(HttpRequestImpl r) {
+        CompletableFuture<Void> cf = new MinimalFuture<>();
+        try {
+            requestFilters(r);
+            cf.complete(null);
+        } catch(Throwable e) {
+            cf.completeExceptionally(e);
+        }
+        return cf;
+    }
+
+
+    private Pair<Response,HttpRequestImpl>
+    responseFilters(Response response) throws IOException
+    {
+        Log.logTrace("Applying response filters");
+        for (HeaderFilter filter : filters) {
+            Log.logTrace("Applying {0}", filter);
+            HttpRequestImpl newreq = filter.response(response);
+            if (newreq != null) {
+                Log.logTrace("New request: stopping filters");
+                return pair(null, newreq);
+            }
+        }
+        Log.logTrace("All filters applied");
+        return pair(response, null);
+    }
+
+    private CompletableFuture<Pair<Response,HttpRequestImpl>>
+    responseFiltersAsync(Response response)
+    {
+        CompletableFuture<Pair<Response,HttpRequestImpl>> cf = new MinimalFuture<>();
+        try {
+            Pair<Response,HttpRequestImpl> n = responseFilters(response); // assumed to be fast
+            cf.complete(n);
+        } catch (Throwable e) {
+            cf.completeExceptionally(e);
+        }
+        return cf;
+    }
+
+    public void cancel() {
+        cancelled = true;
+        getExchange().cancel();
+    }
+
+    public void cancel(IOException cause) {
+        cancelled = true;
+        getExchange().cancel(cause);
+    }
+
+    public CompletableFuture<HttpResponseImpl<T>> responseAsync(Void v) {
+        return responseAsync1(null)
+            .thenCompose((Response r) -> {
+                Exchange<T> exch = getExchange();
+                return exch.readBodyAsync(responseHandler)
+                        .thenApply((T body) -> {
+                            Pair<Response,T> result = new Pair<>(r, body);
+                            return result;
+                        });
+            })
+            .thenApply((Pair<Response,T> result) -> {
+                return new HttpResponseImpl<>(userRequest, result.first, result.second, getExchange());
+            });
+    }
+
+    CompletableFuture<U> multiResponseAsync() {
+        CompletableFuture<HttpResponse<T>> mainResponse = responseAsync(null)
+                  .thenApply((HttpResponseImpl<T> b) -> {
+                      multiResponseHandler.onResponse(b);
+                      return (HttpResponse<T>)b;
+                   });
+
+        pushGroup.setMainResponse(mainResponse);
+        // set up house-keeping related to multi-response
+        mainResponse.thenAccept((r) -> {
+            // All push promises received by now.
+            pushGroup.noMorePushes(true);
+        });
+        return multiResponseHandler.completion(pushGroup.groupResult(), pushGroup.pushesCF());
+    }
+
+    private CompletableFuture<Response> responseAsync1(Void v) {
+        CompletableFuture<Response> cf;
+        if (++attempts > max_attempts) {
+            cf = MinimalFuture.failedFuture(new IOException("Too many retries"));
+        } else {
+            if (currentreq.duration() != null) {
+                timedEvent = new TimedEvent(currentreq.duration());
+                client.registerTimer(timedEvent);
+            }
+            Exchange<T> exch = getExchange();
+            // 1. Apply request filters
+            cf = requestFiltersAsync(currentreq)
+                // 2. get response
+                .thenCompose((v1) -> {
+                    return exch.responseAsync();
+                })
+                // 3. Apply response filters
+                .thenCompose(this::responseFiltersAsync)
+                // 4. Check filter result and repeat or continue
+                .thenCompose((Pair<Response,HttpRequestImpl> pair) -> {
+                    Response resp = pair.first;
+                    if (resp != null) {
+                        if (attempts > 1) {
+                            Log.logError("Succeeded on attempt: " + attempts);
+                        }
+                        return MinimalFuture.completedFuture(resp);
+                    } else {
+                        currentreq = pair.second;
+                        Exchange<T> previous = exch;
+                        setExchange(new Exchange<>(currentreq, this, acc));
+                        //reads body off previous, and then waits for next response
+                        return responseAsync1(null);
+                    }
+                })
+            // 5. Convert result to Pair
+            .handle((BiFunction<Response, Throwable, Pair<Response, Throwable>>) Pair::new)
+            // 6. Handle errors and cancel any timer set
+            .thenCompose((Pair<Response,Throwable> obj) -> {
+                Response response = obj.first;
+                if (response != null) {
+                    return MinimalFuture.completedFuture(response);
+                }
+                // all exceptions thrown are handled here
+                CompletableFuture<Response> error = getExceptionalCF(obj.second);
+                if (error == null) {
+                    cancelTimer();
+                    return responseAsync1(null);
+                } else {
+                    return error;
+                }
+            });
+        }
+        return cf;
+    }
+
+    /**
+     * Take a Throwable and return a suitable CompletableFuture that is
+     * completed exceptionally.
+     */
+    private CompletableFuture<Response> getExceptionalCF(Throwable t) {
+        if ((t instanceof CompletionException) || (t instanceof ExecutionException)) {
+            if (t.getCause() != null) {
+                t = t.getCause();
+            }
+        }
+        if (cancelled && t instanceof IOException) {
+            t = new HttpTimeoutException("request timed out");
+        }
+        return MinimalFuture.failedFuture(t);
+    }
+
+    class TimedEvent extends TimeoutEvent {
+        TimedEvent(Duration duration) {
+            super(duration);
+        }
+        @Override
+        public void handle() {
+            cancel(new HttpTimeoutException("request timed out"));
+        }
+        @Override
+        public String toString() {
+            return "[deadline = " + deadline() + "]";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiMapResult.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * A {@link java.util.Map} containing the result of a HTTP/2 request and multi-response.
+ * This is one possible implementation of the aggregate result type {@code <U>} returned
+ * from {@link HttpClient#sendAsync(HttpRequest,MultiProcessor) }.
+ * The map is indexed by {@link HttpRequest} and each value is a
+ * {@link java.util.concurrent.CompletableFuture}&lt;
+ * {@link HttpResponse}{@code <V>}&gt;
+ * <p>
+ * A {@code MultiMapResult} is obtained from an invocation such as the one shown below:
+ * <p>
+ * {@link CompletableFuture}&lt;{@code MultiMapResult<V>}&gt;
+ * {@link HttpClient#sendAsync(HttpRequest,
+ * HttpResponse.MultiProcessor) HttpClient.sendAsync(}{@link
+ * HttpResponse.MultiProcessor#asMap(java.util.function.Function)
+ * MultiProcessor.asMap(Function)})
+ *
+ * @param <V> the response body type for all responses
+ */
+public class MultiMapResult<V> implements Map<HttpRequest,CompletableFuture<HttpResponse<V>>> {
+    private final Map<HttpRequest,CompletableFuture<HttpResponse<V>>> map;
+
+    MultiMapResult(Map<HttpRequest,CompletableFuture<HttpResponse<V>>> map) {
+        this.map = map;
+    }
+
+    @Override
+    public int size() {
+        return map.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return map.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    @Override
+    public CompletableFuture<HttpResponse<V>> get(Object key) {
+        return map.get(key);
+    }
+
+    @Override
+    public CompletableFuture<HttpResponse<V>> put(HttpRequest key, CompletableFuture<HttpResponse<V>> value) {
+        return map.put(key, value);
+    }
+
+    @Override
+    public CompletableFuture<HttpResponse<V>> remove(Object key) {
+        return map.remove(key);
+    }
+
+    @Override
+    public void putAll(Map<? extends HttpRequest, ? extends CompletableFuture<HttpResponse<V>>> m) {
+        map.putAll(m);
+    }
+
+    @Override
+    public void clear() {
+        map.clear();
+    }
+
+    @Override
+    public Set<HttpRequest> keySet() {
+        return map.keySet();
+    }
+
+    @Override
+    public Collection<CompletableFuture<HttpResponse<V>>> values() {
+        return map.values();
+    }
+
+    @Override
+    public Set<Entry<HttpRequest, CompletableFuture<HttpResponse<V>>>> entrySet() {
+        return map.entrySet();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainHttpConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import jdk.incubator.http.internal.common.AsyncWriteQueue;
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * Plain raw TCP connection direct to destination. 2 modes
+ * 1) Blocking used by http/1. In this case the connect is actually non
+ *    blocking but the request is sent blocking. The first byte of a response
+ *    is received non-blocking and the remainder of the response is received
+ *    blocking
+ * 2) Non-blocking. In this case (for http/2) the connection is actually opened
+ *    blocking but all reads and writes are done non-blocking under the
+ *    control of a Http2Connection object.
+ */
+class PlainHttpConnection extends HttpConnection implements AsyncConnection {
+
+    protected SocketChannel chan;
+    private volatile boolean connected;
+    private boolean closed;
+
+    // should be volatile to provide proper synchronization(visibility) action
+    private volatile Consumer<ByteBufferReference> asyncReceiver;
+    private volatile Consumer<Throwable> errorReceiver;
+    private volatile Supplier<ByteBufferReference> readBufferSupplier;
+
+    private final AsyncWriteQueue asyncOutputQ = new AsyncWriteQueue(this::asyncOutput);
+
+    private final Object reading = new Object();
+
+    @Override
+    public void startReading() {
+        try {
+            client.registerEvent(new ReadEvent());
+        } catch (IOException e) {
+            shutdown();
+        }
+    }
+
+    class ConnectEvent extends AsyncEvent {
+        CompletableFuture<Void> cf;
+
+        ConnectEvent(CompletableFuture<Void> cf) {
+            super(AsyncEvent.BLOCKING);
+            this.cf = cf;
+        }
+
+        @Override
+        public SelectableChannel channel() {
+            return chan;
+        }
+
+        @Override
+        public int interestOps() {
+            return SelectionKey.OP_CONNECT;
+        }
+
+        @Override
+        public void handle() {
+            try {
+                chan.finishConnect();
+            } catch (IOException e) {
+                cf.completeExceptionally(e);
+            }
+            connected = true;
+            cf.complete(null);
+        }
+
+        @Override
+        public void abort() {
+            close();
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> connectAsync() {
+        CompletableFuture<Void> plainFuture = new MinimalFuture<>();
+        try {
+            chan.configureBlocking(false);
+            chan.connect(address);
+            client.registerEvent(new ConnectEvent(plainFuture));
+        } catch (IOException e) {
+            plainFuture.completeExceptionally(e);
+        }
+        return plainFuture;
+    }
+
+    @Override
+    public void connect() throws IOException {
+        chan.connect(address);
+        connected = true;
+    }
+
+    @Override
+    SocketChannel channel() {
+        return chan;
+    }
+
+    PlainHttpConnection(InetSocketAddress addr, HttpClientImpl client) {
+        super(addr, client);
+        try {
+            this.chan = SocketChannel.open();
+            int bufsize = client.getReceiveBufferSize();
+            chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize);
+            chan.setOption(StandardSocketOptions.TCP_NODELAY, true);
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    @Override
+    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
+        if (getMode() != Mode.ASYNC) {
+            return chan.write(buffers, start, number);
+        }
+        // async
+        buffers = Utils.reduce(buffers, start, number);
+        long n = Utils.remaining(buffers);
+        asyncOutputQ.put(ByteBufferReference.toReferences(buffers));
+        flushAsync();
+        return n;
+    }
+
+    @Override
+    long write(ByteBuffer buffer) throws IOException {
+        if (getMode() != Mode.ASYNC) {
+            return chan.write(buffer);
+        }
+        // async
+        long n = buffer.remaining();
+        asyncOutputQ.put(ByteBufferReference.toReferences(buffer));
+        flushAsync();
+        return n;
+    }
+
+    // handle registered WriteEvent; invoked from SelectorManager thread
+    void flushRegistered() {
+        if (getMode() == Mode.ASYNC) {
+            try {
+                asyncOutputQ.flushDelayed();
+            } catch (IOException e) {
+                // Only IOException caused by closed Queue is expected here
+                shutdown();
+            }
+        }
+    }
+
+    @Override
+    public void writeAsync(ByteBufferReference[] buffers) throws IOException {
+        if (getMode() != Mode.ASYNC) {
+            chan.write(ByteBufferReference.toBuffers(buffers));
+            ByteBufferReference.clear(buffers);
+        } else {
+            asyncOutputQ.put(buffers);
+        }
+    }
+
+    @Override
+    public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+        if (getMode() != Mode.ASYNC) {
+            chan.write(ByteBufferReference.toBuffers(buffers));
+            ByteBufferReference.clear(buffers);
+        } else {
+            // Unordered frames are sent before existing frames.
+            asyncOutputQ.putFirst(buffers);
+        }
+    }
+
+    @Override
+    public void flushAsync() throws IOException {
+        if (getMode() == Mode.ASYNC) {
+            asyncOutputQ.flush();
+        }
+    }
+
+    void asyncOutput(ByteBufferReference[] refs, AsyncWriteQueue delayCallback) {
+        try {
+            ByteBuffer[] bufs = ByteBufferReference.toBuffers(refs);
+            while (Utils.remaining(bufs) > 0) {
+                long n = chan.write(bufs);
+                if (n == 0) {
+                    delayCallback.setDelayed(refs);
+                    client.registerEvent(new WriteEvent());
+                    return;
+                }
+            }
+            ByteBufferReference.clear(refs);
+        } catch (IOException e) {
+            shutdown();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "PlainHttpConnection: " + super.toString();
+    }
+
+    /**
+     * Close this connection
+     */
+    @Override
+    public synchronized void close() {
+        if (closed) {
+            return;
+        }
+        closed = true;
+        try {
+            Log.logError("Closing: " + toString());
+            //System.out.println("Closing: " + this);
+            chan.close();
+        } catch (IOException e) {}
+    }
+
+    @Override
+    void shutdownInput() throws IOException {
+        chan.shutdownInput();
+    }
+
+    @Override
+    void shutdownOutput() throws IOException {
+        chan.shutdownOutput();
+    }
+
+    void shutdown() {
+        close();
+        errorReceiver.accept(new IOException("Connection aborted"));
+    }
+
+    void asyncRead() {
+        synchronized (reading) {
+            try {
+                while (true) {
+                    ByteBufferReference buf = readBufferSupplier.get();
+                    int n = chan.read(buf.get());
+                    //System.err.printf("Read %d bytes from chan\n", n);
+                    if (n == -1) {
+                        throw new IOException();
+                    }
+                    if (n == 0) {
+                        buf.clear();
+                        return;
+                    }
+                    buf.get().flip();
+                    asyncReceiver.accept(buf);
+                }
+            } catch (IOException e) {
+                shutdown();
+            }
+        }
+    }
+
+    @Override
+    protected ByteBuffer readImpl() throws IOException {
+        ByteBuffer dst = ByteBuffer.allocate(8192);
+        int n = readImpl(dst);
+        if (n > 0) {
+            return dst;
+        } else if (n == 0) {
+            return Utils.EMPTY_BYTEBUFFER;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    protected int readImpl(ByteBuffer buf) throws IOException {
+        int mark = buf.position();
+        int n;
+        // FIXME: this hack works in conjunction with the corresponding change
+        // in jdk.incubator.http.RawChannel.registerEvent
+        //if ((n = buffer.remaining()) != 0) {
+            //buf.put(buffer);
+        //} else {
+            n = chan.read(buf);
+        //}
+        if (n == -1) {
+            return -1;
+        }
+        Utils.flipToMark(buf, mark);
+        String s = "Receive (" + n + " bytes) ";
+        //debugPrint(s, buf);
+        return n;
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return new ConnectionPool.CacheKey(address, null);
+    }
+
+    @Override
+    synchronized boolean connected() {
+        return connected;
+    }
+
+    // used for all output in HTTP/2
+    class WriteEvent extends AsyncEvent {
+        WriteEvent() {
+            super(0);
+        }
+
+        @Override
+        public SelectableChannel channel() {
+            return chan;
+        }
+
+        @Override
+        public int interestOps() {
+            return SelectionKey.OP_WRITE;
+        }
+
+        @Override
+        public void handle() {
+            flushRegistered();
+        }
+
+        @Override
+        public void abort() {
+            shutdown();
+        }
+    }
+
+    // used for all input in HTTP/2
+    class ReadEvent extends AsyncEvent {
+        ReadEvent() {
+            super(AsyncEvent.REPEATING); // && !BLOCKING
+        }
+
+        @Override
+        public SelectableChannel channel() {
+            return chan;
+        }
+
+        @Override
+        public int interestOps() {
+            return SelectionKey.OP_READ;
+        }
+
+        @Override
+        public void handle() {
+            asyncRead();
+        }
+
+        @Override
+        public void abort() {
+            shutdown();
+        }
+
+    }
+
+    // used in blocking channels only
+    class ReceiveResponseEvent extends AsyncEvent {
+        CompletableFuture<Void> cf;
+
+        ReceiveResponseEvent(CompletableFuture<Void> cf) {
+            super(AsyncEvent.BLOCKING);
+            this.cf = cf;
+        }
+        @Override
+        public SelectableChannel channel() {
+            return chan;
+        }
+
+        @Override
+        public void handle() {
+            cf.complete(null);
+        }
+
+        @Override
+        public int interestOps() {
+            return SelectionKey.OP_READ;
+        }
+
+        @Override
+        public void abort() {
+            close();
+        }
+    }
+
+    @Override
+    boolean isSecure() {
+        return false;
+    }
+
+    @Override
+    boolean isProxied() {
+        return false;
+    }
+
+    @Override
+    public void setAsyncCallbacks(Consumer<ByteBufferReference> asyncReceiver,
+                                  Consumer<Throwable> errorReceiver,
+                                  Supplier<ByteBufferReference> readBufferSupplier) {
+        this.asyncReceiver = asyncReceiver;
+        this.errorReceiver = errorReceiver;
+        this.readBufferSupplier = readBufferSupplier;
+    }
+
+    @Override
+    CompletableFuture<Void> whenReceivingResponse() {
+        CompletableFuture<Void> cf = new MinimalFuture<>();
+        try {
+            client.registerEvent(new ReceiveResponseEvent(cf));
+        } catch (IOException e) {
+            cf.completeExceptionally(e);
+        }
+        return cf;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainProxyConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.net.InetSocketAddress;
+
+class PlainProxyConnection extends PlainHttpConnection {
+
+    PlainProxyConnection(InetSocketAddress proxy, HttpClientImpl client) {
+        super(proxy, client);
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return new ConnectionPool.CacheKey(null, address);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.MinimalFuture;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * A plain text socket tunnel through a proxy. Uses "CONNECT" but does not
+ * encrypt. Used by WebSockets. Subclassed in SSLTunnelConnection for encryption.
+ */
+class PlainTunnelingConnection extends HttpConnection {
+
+    final PlainHttpConnection delegate;
+    protected final InetSocketAddress proxyAddr;
+    private volatile boolean connected;
+
+    @Override
+    public CompletableFuture<Void> connectAsync() {
+        return delegate.connectAsync()
+            .thenCompose((Void v) -> {
+                HttpRequestImpl req = new HttpRequestImpl("CONNECT", client, address);
+                MultiExchange<Void,Void> mconnectExchange = new MultiExchange<>(req, client, this::ignore);
+                return mconnectExchange.responseAsync(null)
+                    .thenCompose((HttpResponseImpl<Void> resp) -> {
+                        CompletableFuture<Void> cf = new MinimalFuture<>();
+                        if (resp.statusCode() != 200) {
+                            cf.completeExceptionally(new IOException("Tunnel failed"));
+                        } else {
+                            connected = true;
+                            cf.complete(null);
+                        }
+                        return cf;
+                    });
+            });
+    }
+
+    private HttpResponse.BodyProcessor<Void> ignore(int status, HttpHeaders hdrs) {
+        return HttpResponse.BodyProcessor.discard((Void)null);
+    }
+
+    @Override
+    public void connect() throws IOException, InterruptedException {
+        delegate.connect();
+        HttpRequestImpl req = new HttpRequestImpl("CONNECT", client, address);
+        Exchange<?> connectExchange = new Exchange<>(req, null);
+        Response r = connectExchange.responseImpl(delegate);
+        if (r.statusCode() != 200) {
+            throw new IOException("Tunnel failed");
+        }
+        connected = true;
+    }
+
+    @Override
+    boolean connected() {
+        return connected;
+    }
+
+    protected PlainTunnelingConnection(InetSocketAddress addr,
+                                       InetSocketAddress proxy,
+                                       HttpClientImpl client) {
+        super(addr, client);
+        this.proxyAddr = proxy;
+        delegate = new PlainHttpConnection(proxy, client);
+    }
+
+    @Override
+    SocketChannel channel() {
+        return delegate.channel();
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return new ConnectionPool.CacheKey(null, proxyAddr);
+    }
+
+    @Override
+    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
+        return delegate.write(buffers, start, number);
+    }
+
+    @Override
+    long write(ByteBuffer buffer) throws IOException {
+        return delegate.write(buffer);
+    }
+
+    @Override
+    void writeAsync(ByteBufferReference[] buffers) throws IOException {
+        delegate.writeAsync(buffers);
+    }
+
+    @Override
+    void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+        delegate.writeAsyncUnordered(buffers);
+    }
+
+    @Override
+    void flushAsync() throws IOException {
+        delegate.flushAsync();
+    }
+
+    @Override
+    public void close() {
+        delegate.close();
+        connected = false;
+    }
+
+    @Override
+    void shutdownInput() throws IOException {
+        delegate.shutdownInput();
+    }
+
+    @Override
+    void shutdownOutput() throws IOException {
+        delegate.shutdownOutput();
+    }
+
+    @Override
+    CompletableFuture<Void> whenReceivingResponse() {
+        return delegate.whenReceivingResponse();
+    }
+
+    @Override
+    protected ByteBuffer readImpl() throws IOException {
+        return delegate.readImpl();
+    }
+
+    @Override
+    protected int readImpl(ByteBuffer buffer) throws IOException {
+        return delegate.readImpl(buffer);
+    }
+
+    @Override
+    boolean isSecure() {
+        return false;
+    }
+
+    @Override
+    boolean isProxied() {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PseudoPublisher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.concurrent.Flow;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+// Completes the subscription on first request. Never calls onNext()
+
+class PseudoPublisher<T> implements Flow.Publisher<T> {
+
+    private final Throwable throwable;
+
+    PseudoPublisher() {
+        this(null);
+    }
+
+    PseudoPublisher(Throwable throwable) {
+        this.throwable = throwable;
+    }
+
+    @Override
+    public void subscribe(Flow.Subscriber<? super T> subscriber) {
+        subscriber.onSubscribe(new Subscription(subscriber));
+    }
+
+    private class Subscription implements Flow.Subscription {
+
+        private final Flow.Subscriber<? super T> subscriber;
+        private final AtomicBoolean done = new AtomicBoolean();
+
+        Subscription(Flow.Subscriber<? super T> subscriber) {
+            this.subscriber = subscriber;
+        }
+
+        @Override
+        public void request(long n) {
+            if (done.compareAndSet(false, true)) {
+                if (n > 0) {
+                    if (throwable == null) {
+                        subscriber.onComplete();
+                    } else {
+                        subscriber.onError(throwable);
+                    }
+                } else {
+                    subscriber.onError(new IllegalArgumentException("request(" + n + ")"));
+                }
+            }
+        }
+
+        @Override
+        public void cancel() {
+            done.set(true);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PullPublisher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Iterator;
+import java.util.concurrent.Flow;
+
+/**
+ * A Publisher that is expected to run in same thread as subscriber.
+ * Items are obtained from Iterable. Each new subscription gets a new Iterator.
+ */
+class PullPublisher<T> implements Flow.Publisher<T> {
+
+    private final Iterable<T> iterable;
+
+    PullPublisher(Iterable<T> iterable) {
+        this.iterable = iterable;
+    }
+
+    @Override
+    public void subscribe(Flow.Subscriber<? super T> subscriber) {
+        subscriber.onSubscribe(new Subscription(subscriber, iterable.iterator()));
+    }
+
+    private class Subscription implements Flow.Subscription {
+
+        private final Flow.Subscriber<? super T> subscriber;
+        private final Iterator<T> iter;
+        private boolean done = false;
+        private long demand = 0;
+        private int recursion = 0;
+
+        Subscription(Flow.Subscriber<? super T> subscriber, Iterator<T> iter) {
+            this.subscriber = subscriber;
+            this.iter = iter;
+        }
+
+        @Override
+        public void request(long n) {
+            if (done) {
+                subscriber.onError(new IllegalArgumentException("request(" + n + ")"));
+            }
+            demand += n;
+            recursion ++;
+            if (recursion > 1) {
+                return;
+            }
+            while (demand > 0) {
+                done = !iter.hasNext();
+                if (done) {
+                    subscriber.onComplete();
+                    recursion --;
+                    return;
+                }
+                subscriber.onNext(iter.next());
+                demand --;
+            }
+        }
+
+        @Override
+        public void cancel() {
+            done = true;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PushGroup.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.concurrent.CompletableFuture;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Log;
+
+/**
+ * One PushGroup object is associated with the parent Stream of the pushed
+ * Streams. This keeps track of all common state associated with the pushes.
+ */
+class PushGroup<U,T> {
+    // the overall completion object, completed when all pushes are done.
+    final CompletableFuture<Void> resultCF;
+    final CompletableFuture<Void> noMorePushesCF;
+
+    volatile Throwable error; // any exception that occured during pushes
+
+    // CF for main response
+    final CompletableFuture<HttpResponse<T>> mainResponse;
+
+    // user's processor object
+    final HttpResponse.MultiProcessor<U, T> multiProcessor;
+
+    final HttpResponse.BodyHandler<T> mainBodyHandler;
+
+    int numberOfPushes;
+    int remainingPushes;
+    boolean noMorePushes = false;
+
+    PushGroup(HttpResponse.MultiProcessor<U, T> multiProcessor, HttpRequestImpl req) {
+        this(multiProcessor, req, new MinimalFuture<>());
+    }
+
+    // Check mainBodyHandler before calling nested constructor.
+    private PushGroup(HttpResponse.MultiProcessor<U, T> multiProcessor,
+            HttpRequestImpl req,
+            CompletableFuture<HttpResponse<T>> mainResponse) {
+        this(multiProcessor, mainResponse,
+             multiProcessor.onRequest(req).orElseThrow(
+                    () -> new IllegalArgumentException(
+                     "A valid body processor for the main response is required")));
+    }
+
+    // This private constructor is called after all parameters have been
+    // checked.
+    private PushGroup(HttpResponse.MultiProcessor<U, T> multiProcessor,
+                      CompletableFuture<HttpResponse<T>> mainResponse,
+                      HttpResponse.BodyHandler<T> mainBodyHandler) {
+
+        assert mainResponse != null; // A new instance is created above
+        assert mainBodyHandler != null; // should have been checked above
+
+        this.resultCF = new MinimalFuture<>();
+        this.noMorePushesCF = new MinimalFuture<>();
+        this.multiProcessor = multiProcessor;
+        this.mainResponse = mainResponse.thenApply(r -> {
+            multiProcessor.onResponse(r);
+            return r;
+        });
+        this.mainBodyHandler = mainBodyHandler;
+    }
+
+    CompletableFuture<Void> groupResult() {
+        return resultCF;
+    }
+
+    HttpResponse.MultiProcessor<U, T> processor() {
+        return multiProcessor;
+    }
+
+    HttpResponse.BodyHandler<T> mainResponseHandler() {
+        return mainBodyHandler;
+    }
+
+    synchronized void setMainResponse(CompletableFuture<HttpResponse<T>> r) {
+        r.whenComplete((HttpResponse<T> response, Throwable t) -> {
+            if (t != null)
+                mainResponse.completeExceptionally(t);
+            else
+                mainResponse.complete(response);
+        });
+    }
+
+    synchronized CompletableFuture<HttpResponse<T>> mainResponse() {
+        return mainResponse;
+    }
+
+    synchronized void addPush() {
+        numberOfPushes++;
+        remainingPushes++;
+    }
+
+    synchronized int numberOfPushes() {
+        return numberOfPushes;
+    }
+    // This is called when the main body response completes because it means
+    // no more PUSH_PROMISEs are possible
+
+    synchronized void noMorePushes(boolean noMore) {
+        noMorePushes = noMore;
+        checkIfCompleted();
+        noMorePushesCF.complete(null);
+    }
+
+    CompletableFuture<Void> pushesCF() {
+        return noMorePushesCF;
+    }
+
+    synchronized boolean noMorePushes() {
+        return noMorePushes;
+    }
+
+    synchronized void pushCompleted() {
+        remainingPushes--;
+        checkIfCompleted();
+    }
+
+    synchronized void checkIfCompleted() {
+        if (Log.trace()) {
+            Log.logTrace("PushGroup remainingPushes={0} error={1} noMorePushes={2}",
+                         remainingPushes,
+                         (error==null)?error:error.getClass().getSimpleName(),
+                         noMorePushes);
+        }
+        if (remainingPushes == 0 && error == null && noMorePushes) {
+            if (Log.trace()) {
+                Log.logTrace("push completed");
+            }
+            resultCF.complete(null);
+        }
+    }
+
+    synchronized void pushError(Throwable t) {
+        if (t == null) {
+            return;
+        }
+        this.error = t;
+        resultCF.completeExceptionally(t);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PushPublisher.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Optional;
+import java.util.concurrent.Flow;
+import java.util.function.Consumer;
+
+/**
+ * A single threaded Publisher which runs in same thread as subscriber.
+ */
+class PushPublisher<T> extends AbstractPushPublisher<T> {
+    Subscription subscription;
+    Flow.Subscriber<? super T> subscriber;
+    SubscriptionState state;
+    long demand;
+
+    /**
+     * Pushes/consumes the incoming objects.
+     * The consumer blocks until subscriber ready to receive.
+     */
+    @Override
+    public void acceptData(Optional<T> item) {
+        SubscriptionState s = this.state;
+
+        if (s == SubscriptionState.CANCELLED) return;
+        if (s == SubscriptionState.DONE) {
+            throw new IllegalStateException("subscription complete");
+        }
+
+        if (!item.isPresent()) {
+            subscriber.onComplete();
+            this.state = SubscriptionState.DONE;
+            return;
+        }
+        if (demand == 0) {
+            throw new IllegalStateException("demand == 0");
+        }
+        demand--;
+        subscriber.onNext(item.get());
+    }
+
+    @Override
+    public Consumer<Optional<T>> asDataConsumer() {
+        return this::acceptData;
+    }
+
+    @Override
+    public void subscribe(Flow.Subscriber<? super T> subscriber) {
+        subscription = new Subscription(subscriber);
+        subscriber.onSubscribe(subscription);
+    }
+
+    private class Subscription implements Flow.Subscription {
+
+        Subscription(Flow.Subscriber<? super T> subscriber) {
+            PushPublisher.this.subscriber = subscriber;
+        }
+
+        @Override
+        public void request(long n) {
+            demand += n;
+        }
+
+        @Override
+        public void cancel() {
+            state = SubscriptionState.CANCELLED;
+        }
+    }
+
+    @Override
+    public void acceptError(Throwable t) {
+        if (this.state == SubscriptionState.DONE) {
+            throw new IllegalStateException("subscription complete");
+        }
+        this.state = SubscriptionState.CANCELLED;
+        subscriber.onError(t);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/RawChannelImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import jdk.incubator.http.internal.common.Utils;
+import jdk.incubator.http.internal.websocket.RawChannel;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SocketChannel;
+
+/*
+ * Each RawChannel corresponds to a TCP connection (SocketChannel) but is
+ * connected to a Selector and an ExecutorService for invoking the send and
+ * receive callbacks. Also includes SSL processing.
+ */
+final class RawChannelImpl implements RawChannel {
+
+    private final HttpClientImpl client;
+    private final HttpConnection connection;
+    private final Object         initialLock = new Object();
+    private ByteBuffer           initial;
+
+    RawChannelImpl(HttpClientImpl client,
+                   HttpConnection connection,
+                   ByteBuffer initial)
+            throws IOException
+    {
+        this.client = client;
+        this.connection = connection;
+        SocketChannel chan = connection.channel();
+        client.cancelRegistration(chan);
+        // Constructing a RawChannel is supposed to have a "hand over"
+        // semantics, in other words if construction fails, the channel won't be
+        // needed by anyone, in which case someone still needs to close it
+        try {
+            chan.configureBlocking(false);
+        } catch (IOException e) {
+            try {
+                chan.close();
+            } catch (IOException e1) {
+                e.addSuppressed(e1);
+            }
+            throw e;
+        }
+        // empty the initial buffer into our own copy.
+        synchronized (initialLock) {
+            this.initial = initial.hasRemaining()
+                    ? Utils.copy(initial)
+                    : Utils.EMPTY_BYTEBUFFER;
+        }
+    }
+
+    private class NonBlockingRawAsyncEvent extends AsyncEvent {
+
+        private final RawEvent re;
+
+        NonBlockingRawAsyncEvent(RawEvent re) {
+            super(0); // !BLOCKING & !REPEATING
+            this.re = re;
+        }
+
+        @Override
+        public SelectableChannel channel() {
+            return connection.channel();
+        }
+
+        @Override
+        public int interestOps() {
+            return re.interestOps();
+        }
+
+        @Override
+        public void handle() {
+            re.handle();
+        }
+
+        @Override
+        public void abort() { }
+    }
+
+    @Override
+    public void registerEvent(RawEvent event) throws IOException {
+        client.registerEvent(new NonBlockingRawAsyncEvent(event));
+    }
+
+    @Override
+    public ByteBuffer read() throws IOException {
+        assert !connection.channel().isBlocking();
+        return connection.read();
+    }
+
+    @Override
+    public ByteBuffer initialByteBuffer() {
+        synchronized (initialLock) {
+            if (initial == null) {
+                throw new IllegalStateException();
+            }
+            ByteBuffer ref = initial;
+            initial = null;
+            return ref;
+        }
+    }
+
+    @Override
+    public long write(ByteBuffer[] src, int offset, int len) throws IOException {
+        return connection.write(src, offset, len);
+    }
+
+    @Override
+    public void shutdownInput() throws IOException {
+        connection.shutdownInput();
+    }
+
+    @Override
+    public void shutdownOutput() throws IOException {
+        connection.shutdownOutput();
+    }
+
+    @Override
+    public void close() throws IOException {
+        connection.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/RedirectFilter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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.  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.incubator.http;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import jdk.incubator.http.internal.common.Utils;
+
+class RedirectFilter implements HeaderFilter {
+
+    HttpRequestImpl request;
+    HttpClientImpl client;
+    HttpClient.Redirect policy;
+    String method;
+    MultiExchange<?,?> exchange;
+    static final int DEFAULT_MAX_REDIRECTS = 5;
+    URI uri;
+
+    static final int max_redirects = Utils.getIntegerNetProperty(
+            "jdk.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS
+    );
+
+    @Override
+    public synchronized void request(HttpRequestImpl r, MultiExchange<?,?> e) throws IOException {
+        this.request = r;
+        this.client = e.client();
+        this.policy = client.followRedirects();
+
+        this.method = r.method();
+        this.uri = r.uri();
+        this.exchange = e;
+    }
+
+    @Override
+    public synchronized HttpRequestImpl response(Response r) throws IOException {
+        return handleResponse(r);
+    }
+
+    /**
+     * checks to see if new request needed and returns it.
+     * Null means response is ok to return to user.
+     */
+    private HttpRequestImpl handleResponse(Response r) {
+        int rcode = r.statusCode();
+        if (rcode == 200 || policy == HttpClient.Redirect.NEVER) {
+            return null;
+        }
+        if (rcode >= 300 && rcode <= 399) {
+            URI redir = getRedirectedURI(r.headers());
+            if (canRedirect(redir) && ++exchange.numberOfRedirects < max_redirects) {
+                //System.out.println("Redirecting to: " + redir);
+                return new HttpRequestImpl(redir, method, request);
+            } else {
+                //System.out.println("Redirect: giving up");
+                return null;
+            }
+        }
+        return null;
+    }
+
+    private URI getRedirectedURI(HttpHeaders headers) {
+        URI redirectedURI;
+        String ss = headers.firstValue("Location").orElse("Not present");
+        redirectedURI = headers.firstValue("Location")
+                .map((s) -> URI.create(s))
+                .orElseThrow(() -> new UncheckedIOException(
+                        new IOException("Invalid redirection")));
+
+        // redirect could be relative to original URL, but if not
+        // then redirect is used.
+        redirectedURI = uri.resolve(redirectedURI);
+        return redirectedURI;
+    }
+
+    private boolean canRedirect(URI redir) {
+        String newScheme = redir.getScheme();
+        String oldScheme = uri.getScheme();
+        switch (policy) {
+            case ALWAYS:
+                return true;
+            case NEVER:
+                return false;
+            case SECURE:
+                return newScheme.equalsIgnoreCase("https");
+            case SAME_PROTOCOL:
+                return newScheme.equalsIgnoreCase(oldScheme);
+            default:
+                throw new InternalError();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/RequestProcessors.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Flow;
+import java.util.function.Supplier;
+import jdk.incubator.http.internal.common.Utils;
+
+class RequestProcessors {
+    // common base class for Publisher and Subscribers used here
+    abstract static class ProcessorBase {
+        HttpClientImpl client;
+
+        synchronized void setClient(HttpClientImpl client) {
+            this.client = client;
+        }
+
+        synchronized HttpClientImpl getClient() {
+            return client;
+        }
+    }
+
+    static class ByteArrayProcessor extends ProcessorBase
+        implements HttpRequest.BodyProcessor
+    {
+        private volatile Flow.Publisher<ByteBuffer> delegate;
+        private final int length;
+        private final byte[] content;
+        private final int offset;
+
+        ByteArrayProcessor(byte[] content) {
+            this(content, 0, content.length);
+        }
+
+        ByteArrayProcessor(byte[] content, int offset, int length) {
+            this.content = content;
+            this.offset = offset;
+            this.length = length;
+        }
+
+        List<ByteBuffer> copy(byte[] content, int offset, int length) {
+            List<ByteBuffer> bufs = new ArrayList<>();
+            while (length > 0) {
+                ByteBuffer b = ByteBuffer.allocate(Math.min(Utils.BUFSIZE, length));
+                int max = b.capacity();
+                int tocopy = Math.min(max, length);
+                b.put(content, offset, tocopy);
+                offset += tocopy;
+                length -= tocopy;
+                b.flip();
+                bufs.add(b);
+            }
+            return bufs;
+        }
+
+        @Override
+        public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
+            List<ByteBuffer> copy = copy(content, offset, length);
+            this.delegate = new PullPublisher<>(copy);
+            delegate.subscribe(subscriber);
+        }
+
+        @Override
+        public long contentLength() {
+            return length;
+        }
+    }
+
+    // This implementation has lots of room for improvement.
+    static class IterableProcessor extends ProcessorBase
+        implements HttpRequest.BodyProcessor
+    {
+        private volatile Flow.Publisher<ByteBuffer> delegate;
+        private final Iterable<byte[]> content;
+        private volatile long contentLength;
+
+        IterableProcessor(Iterable<byte[]> content) {
+            this.content = content;
+        }
+
+        // The ByteBufferIterator will iterate over the byte[] arrays in
+        // the content one at the time.
+        //
+        class ByteBufferIterator implements Iterator<ByteBuffer> {
+            final ConcurrentLinkedQueue<ByteBuffer> buffers = new ConcurrentLinkedQueue<>();
+            final Iterator<byte[]> iterator = content.iterator();
+            @Override
+            public boolean hasNext() {
+                return !buffers.isEmpty() || iterator.hasNext();
+            }
+
+            @Override
+            public ByteBuffer next() {
+                ByteBuffer buffer = buffers.poll();
+                while (buffer == null) {
+                    copy();
+                    buffer = buffers.poll();
+                }
+                return buffer;
+            }
+
+            ByteBuffer getBuffer() {
+                return Utils.getBuffer();
+            }
+
+            void copy() {
+                byte[] bytes = iterator.next();
+                int length = bytes.length;
+                if (length == 0 && iterator.hasNext()) {
+                    // avoid inserting empty buffers, except
+                    // if that's the last.
+                    return;
+                }
+                int offset = 0;
+                do {
+                    ByteBuffer b = getBuffer();
+                    int max = b.capacity();
+
+                    int tocopy = Math.min(max, length);
+                    b.put(bytes, offset, tocopy);
+                    offset += tocopy;
+                    length -= tocopy;
+                    b.flip();
+                    buffers.add(b);
+                } while (length > 0);
+            }
+        }
+
+        public Iterator<ByteBuffer> iterator() {
+            return new ByteBufferIterator();
+        }
+
+        @Override
+        public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
+            Iterable<ByteBuffer> iterable = this::iterator;
+            this.delegate = new PullPublisher<>(iterable);
+            delegate.subscribe(subscriber);
+        }
+
+        static long computeLength(Iterable<byte[]> bytes) {
+            long len = 0;
+            for (byte[] b : bytes) {
+                len = Math.addExact(len, (long)b.length);
+            }
+            return len;
+        }
+
+        @Override
+        public long contentLength() {
+            if (contentLength == 0) {
+                synchronized(this) {
+                    if (contentLength == 0) {
+                        contentLength = computeLength(content);
+                    }
+                }
+            }
+            return contentLength;
+        }
+    }
+
+    static class StringProcessor extends ByteArrayProcessor {
+        public StringProcessor(String content, Charset charset) {
+            super(content.getBytes(charset));
+        }
+    }
+
+    static class EmptyProcessor extends ProcessorBase implements HttpRequest.BodyProcessor
+    {
+        PseudoPublisher<ByteBuffer> delegate = new PseudoPublisher<>();
+
+        @Override
+        public long contentLength() {
+            return 0;
+        }
+
+        @Override
+        public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
+            delegate.subscribe(subscriber);
+        }
+    }
+
+    static class FileProcessor extends InputStreamProcessor
+        implements HttpRequest.BodyProcessor
+    {
+        File file;
+
+        FileProcessor(Path name) {
+            super(() -> create(name));
+            file = name.toFile();
+        }
+
+        static FileInputStream create(Path name) {
+            try {
+                return new FileInputStream(name.toFile());
+            } catch (FileNotFoundException e) {
+                throw new UncheckedIOException(e);
+            }
+        }
+        @Override
+        public long contentLength() {
+            return file.length();
+        }
+    }
+
+    /**
+     * Reads one buffer ahead all the time, blocking in hasNext()
+     */
+    static class StreamIterator implements Iterator<ByteBuffer> {
+        final InputStream is;
+        ByteBuffer nextBuffer;
+        boolean need2Read = true;
+        boolean haveNext;
+        Throwable error;
+
+        StreamIterator(InputStream is) {
+            this.is = is;
+        }
+
+        Throwable error() {
+            return error;
+        }
+
+        private int read() {
+            nextBuffer = Utils.getBuffer();
+            nextBuffer.clear();
+            byte[] buf = nextBuffer.array();
+            int offset = nextBuffer.arrayOffset();
+            int cap = nextBuffer.capacity();
+            try {
+                int n = is.read(buf, offset, cap);
+                if (n == -1) {
+                    is.close();
+                    return -1;
+                }
+                //flip
+                nextBuffer.limit(n);
+                nextBuffer.position(0);
+                return n;
+            } catch (IOException ex) {
+                error = ex;
+                return -1;
+            }
+        }
+
+        @Override
+        public synchronized boolean hasNext() {
+            if (need2Read) {
+                haveNext = read() != -1;
+                if (haveNext) {
+                    need2Read = false;
+                }
+                return haveNext;
+            }
+            return haveNext;
+        }
+
+        @Override
+        public synchronized ByteBuffer next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            need2Read = true;
+            return nextBuffer;
+        }
+
+    }
+
+    static class InputStreamProcessor extends ProcessorBase
+        implements HttpRequest.BodyProcessor
+    {
+        private final Supplier<? extends InputStream> streamSupplier;
+        private Flow.Publisher<ByteBuffer> delegate;
+
+        InputStreamProcessor(Supplier<? extends InputStream> streamSupplier) {
+            this.streamSupplier = streamSupplier;
+        }
+
+        @Override
+        public synchronized void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
+            if (!(subscriber instanceof ProcessorBase)) {
+                throw new UnsupportedOperationException();
+            }
+            ProcessorBase base = (ProcessorBase)subscriber;
+            HttpClientImpl client = base.getClient();
+            InputStream is = streamSupplier.get();
+            if (is == null) {
+                throw new UncheckedIOException(new IOException("no inputstream supplied"));
+            }
+            this.delegate = new PullPublisher<>(() -> new StreamIterator(is));
+            delegate.subscribe(subscriber);
+        }
+
+        @Override
+        public long contentLength() {
+            return -1;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Response.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+/**
+ * Response headers and status code.
+ */
+class Response {
+    final HttpHeaders headers;
+    final int statusCode;
+    final HttpRequestImpl request;
+    final Exchange<?> exchange;
+    final HttpClient.Version version;
+
+    Response(HttpRequestImpl req,
+             Exchange<?> exchange,
+             HttpHeaders headers,
+             int statusCode,
+             HttpClient.Version version) {
+        this.headers = headers;
+        this.request = req;
+        this.version = version;
+        this.exchange = exchange;
+        this.statusCode = statusCode;
+    }
+
+    HttpRequestImpl request() {
+        return request;
+    }
+
+    HttpClient.Version version() {
+        return version;
+    }
+
+    HttpHeaders headers() {
+        return headers;
+    }
+
+    Exchange<?> exchange() {
+        return exchange;
+    }
+
+    int statusCode() {
+        return statusCode;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseContent.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Optional;
+import java.util.function.Consumer;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * Implements chunked/fixed transfer encodings of HTTP/1.1 responses.
+ *
+ * Call pushBody() to read the body (blocking). Data and errors are provided
+ * to given Consumers. After final buffer delivered, empty optional delivered
+ */
+class ResponseContent {
+
+    final HttpResponse.BodyProcessor<?> pusher;
+    final HttpConnection connection;
+    final int contentLength;
+    ByteBuffer buffer;
+    //ByteBuffer lastBufferUsed;
+    final ResponseHeaders headers;
+    private final Consumer<Optional<ByteBuffer>> dataConsumer;
+    private final Consumer<IOException> errorConsumer;
+    private final HttpClientImpl client;
+    // this needs to run before we complete the body
+    // so that connection can be returned to pool
+    private final Runnable onFinished;
+
+    ResponseContent(HttpConnection connection,
+                    int contentLength,
+                    ResponseHeaders h,
+                    HttpResponse.BodyProcessor<?> userProcessor,
+                    Consumer<Optional<ByteBuffer>> dataConsumer,
+                    Consumer<IOException> errorConsumer,
+                    Runnable onFinished)
+    {
+        this.pusher = (HttpResponse.BodyProcessor)userProcessor;
+        this.connection = connection;
+        this.contentLength = contentLength;
+        this.headers = h;
+        this.dataConsumer = dataConsumer;
+        this.errorConsumer = errorConsumer;
+        this.client = connection.client;
+        this.onFinished = onFinished;
+    }
+
+    static final int LF = 10;
+    static final int CR = 13;
+    static final int SP = 0x20;
+    static final int BUF_SIZE = 1024;
+
+    boolean chunkedContent, chunkedContentInitialized;
+
+    private boolean contentChunked() throws IOException {
+        if (chunkedContentInitialized) {
+            return chunkedContent;
+        }
+        if (contentLength == -1) {
+            String tc = headers.firstValue("Transfer-Encoding")
+                               .orElse("");
+            if (!tc.equals("")) {
+                if (tc.equalsIgnoreCase("chunked")) {
+                    chunkedContent = true;
+                } else {
+                    throw new IOException("invalid content");
+                }
+            } else {
+                chunkedContent = false;
+            }
+        }
+        chunkedContentInitialized = true;
+        return chunkedContent;
+    }
+
+    /**
+     * Entry point for pusher. b is an initial ByteBuffer that may
+     * have some data in it. When this method returns, the body
+     * has been fully processed.
+     */
+    void pushBody(ByteBuffer b) {
+        try {
+            // TODO: check status
+            if (contentChunked()) {
+                pushBodyChunked(b);
+            } else {
+                pushBodyFixed(b);
+            }
+        } catch (IOException t) {
+            errorConsumer.accept(t);
+        }
+    }
+
+    // reads and returns chunklen. Position of chunkbuf is first byte
+    // of chunk on return. chunklen includes the CR LF at end of chunk
+    int readChunkLen() throws IOException {
+        chunklen = 0;
+        boolean cr = false;
+        while (true) {
+            getHunk();
+            int c = chunkbuf.get();
+            if (cr) {
+                if (c == LF) {
+                    return chunklen + 2;
+                } else {
+                    throw new IOException("invalid chunk header");
+                }
+            }
+            if (c == CR) {
+                cr = true;
+            } else {
+                int digit = toDigit(c);
+                chunklen = chunklen * 16 + digit;
+            }
+        }
+    }
+
+    int chunklen = -1;      // number of bytes in chunk (fixed)
+    int bytesremaining;     // number of bytes in chunk left to be read incl CRLF
+    int bytesread;
+    ByteBuffer chunkbuf;    // initialise
+
+    // make sure we have at least 1 byte to look at
+    private void getHunk() throws IOException {
+        if (chunkbuf == null || !chunkbuf.hasRemaining()) {
+            if (chunkbuf == null) {
+                chunkbuf = Utils.getBuffer();
+            }
+            chunkbuf.clear();
+            connection.read(chunkbuf);
+        }
+    }
+
+    private void consumeBytes(int n) throws IOException {
+        getHunk();
+        while (n > 0) {
+            int e = Math.min(chunkbuf.remaining(), n);
+            chunkbuf.position(chunkbuf.position() + e);
+            n -= e;
+            if (n > 0) {
+                getHunk();
+            }
+        }
+    }
+
+    /**
+     * Returns a ByteBuffer containing a chunk of data or a "hunk" of data
+     * (a chunk of a chunk if the chunk size is larger than our ByteBuffers).
+     * ByteBuffer returned is obtained from response processor.
+     */
+    ByteBuffer readChunkedBuffer() throws IOException {
+        if (chunklen == -1) {
+            // new chunk
+            chunklen = readChunkLen() - 2;
+            bytesremaining =  chunklen;
+            if (chunklen == 0) {
+                consumeBytes(2);
+                return null;
+            }
+        }
+
+        getHunk();
+        bytesread = chunkbuf.remaining();
+        ByteBuffer returnBuffer = Utils.getBuffer();
+        int space = returnBuffer.remaining();
+
+        int bytes2Copy = Math.min(bytesread, Math.min(bytesremaining, space));
+        Utils.copy(chunkbuf, returnBuffer, bytes2Copy);
+        returnBuffer.flip();
+        bytesremaining -= bytes2Copy;
+        if (bytesremaining == 0) {
+            consumeBytes(2);
+            chunklen = -1;
+        }
+        return returnBuffer;
+    }
+
+    ByteBuffer initialBuffer;
+    int fixedBytesReturned;
+
+    //ByteBuffer getResidue() {
+        //return lastBufferUsed;
+    //}
+
+    private void compactBuffer(ByteBuffer buf) {
+        buf.compact()
+           .flip();
+    }
+
+    /**
+     * Copies inbuf (numBytes from its position) to new buffer. The returned
+     * buffer's position is zero and limit is at end (numBytes)
+     */
+    private ByteBuffer copyBuffer(ByteBuffer inbuf, int numBytes) {
+        ByteBuffer b1 = Utils.getBuffer();
+        assert b1.remaining() >= numBytes;
+        byte[] b = b1.array();
+        inbuf.get(b, 0, numBytes);
+        b1.limit(numBytes);
+        return b1;
+    }
+
+    private void pushBodyChunked(ByteBuffer b) throws IOException {
+        chunkbuf = b;
+        while (true) {
+            ByteBuffer b1 = readChunkedBuffer();
+            if (b1 != null) {
+                if (b1.hasRemaining()) {
+                    dataConsumer.accept(Optional.of(b1));
+                }
+            } else {
+                onFinished.run();
+                dataConsumer.accept(Optional.empty());
+                return;
+            }
+        }
+    }
+
+    private int toDigit(int b) throws IOException {
+        if (b >= 0x30 && b <= 0x39) {
+            return b - 0x30;
+        }
+        if (b >= 0x41 && b <= 0x46) {
+            return b - 0x41 + 10;
+        }
+        if (b >= 0x61 && b <= 0x66) {
+            return b - 0x61 + 10;
+        }
+        throw new IOException("Invalid chunk header byte " + b);
+    }
+
+    private void pushBodyFixed(ByteBuffer b) throws IOException {
+        int remaining = contentLength;
+        //lastBufferUsed = b;
+        while (b.hasRemaining() && remaining > 0) {
+            ByteBuffer buffer = Utils.getBuffer();
+            int amount = Math.min(b.remaining(), remaining);
+            Utils.copy(b, buffer, amount);
+            remaining -= amount;
+            buffer.flip();
+            dataConsumer.accept(Optional.of(buffer));
+        }
+        //client.returnBuffer(b);
+        while (remaining > 0) {
+            ByteBuffer buffer = Utils.getBuffer();
+            int xx = connection.read(buffer);
+            if (xx == -1)
+                throw new IOException("connection closed");
+
+            int bytesread = buffer.remaining();
+            // assume for now that pipelining not implemented
+            if (bytesread > remaining) {
+                System.err.println("xx = " + xx);
+                System.err.println("bytesread = " + bytesread);
+                System.err.println("remaining = " + remaining);
+                for (int i=0; i<remaining; i++) {
+                    System.err.printf("%x ", buffer.get());
+                }
+                throw new IOException("too many bytes read");
+            }
+            remaining -= bytesread;
+            dataConsumer.accept(Optional.of(buffer));
+        }
+        onFinished.run();
+        dataConsumer.accept(Optional.empty());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseHeaders.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import sun.net.www.MessageHeader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.OptionalLong;
+
+import static java.lang.String.format;
+import static jdk.incubator.http.internal.common.Utils.isValidName;
+import static jdk.incubator.http.internal.common.Utils.isValidValue;
+import static java.util.Objects.requireNonNull;
+
+/*
+ * Reads entire header block off channel, in blocking mode.
+ * This class is not thread-safe.
+ */
+final class ResponseHeaders implements HttpHeaders {
+
+    private static final char CR = '\r';
+    private static final char LF = '\n';
+
+    private final ImmutableHeaders delegate;
+
+    /*
+     * This constructor takes a connection from which the header block is read
+     * and a buffer which may contain an initial portion of this header block.
+     *
+     * After the headers have been parsed (this constructor has returned) the
+     * leftovers (i.e. data, if any, beyond the header block) are accessible
+     * from this same buffer from its position to its limit.
+     */
+    ResponseHeaders(HttpConnection connection, ByteBuffer buffer) throws IOException {
+        requireNonNull(connection);
+        requireNonNull(buffer);
+        InputStreamWrapper input = new InputStreamWrapper(connection, buffer);
+        delegate = ImmutableHeaders.of(parse(input));
+    }
+
+    static final class InputStreamWrapper extends InputStream {
+        final HttpConnection connection;
+        final ByteBuffer buffer;
+        int lastRead = -1; // last byte read from the buffer
+        int consumed = 0; // number of bytes consumed.
+        InputStreamWrapper(HttpConnection connection, ByteBuffer buffer) {
+            super();
+            this.connection = connection;
+            this.buffer = buffer;
+        }
+        @Override
+        public int read() throws IOException {
+            if (!buffer.hasRemaining()) {
+                buffer.clear();
+                int n = connection.read(buffer);
+                if (n == -1) {
+                    return lastRead = -1;
+                }
+            }
+            // don't let consumed become positive again if it overflowed
+            // we just want to make sure that consumed == 1 really means
+            // that only one byte was consumed.
+            if (consumed >= 0) consumed++;
+            return lastRead = buffer.get();
+        }
+    }
+
+    private Map<String, List<String>> parse(InputStreamWrapper input)
+         throws IOException
+    {
+        // The bulk of work is done by this time-proven class
+        MessageHeader h = new MessageHeader();
+        h.parseHeader(input);
+
+        // When there are no headers (and therefore no body), the status line
+        // will be followed by an empty CRLF line.
+        // In that case MessageHeader.parseHeader() will consume the first
+        // CR character and stop there. In this case we must consume the
+        // remaining LF.
+        if (input.consumed == 1 && CR == (char) input.lastRead) {
+            // MessageHeader will not consume LF if the first character it
+            // finds is CR. This only happens if there are no headers, and
+            // only one byte will be consumed from the buffer. In this case
+            // the next byte MUST be LF
+            //System.err.println("Last character read is: " + (byte)lastRead);
+            if (input.read() != LF) {
+                throw new IOException("Unexpected byte sequence when no headers: "
+                     + ((int)CR) + " " + input.lastRead
+                     + "(" + ((int)CR) + " " + ((int)LF) + " expected)");
+            }
+        }
+
+        Map<String, List<String>> rawHeaders = h.getHeaders();
+
+        // Now some additional post-processing to adapt the results received
+        // from MessageHeader to what is needed here
+        Map<String, List<String>> cookedHeaders = new HashMap<>();
+        for (Map.Entry<String, List<String>> e : rawHeaders.entrySet()) {
+            String key = e.getKey();
+            if (key == null) {
+                throw new ProtocolException("Bad header-field");
+            }
+            if (!isValidName(key)) {
+                throw new ProtocolException(format(
+                        "Bad header-name: '%s'", key));
+            }
+            List<String> newValues = e.getValue();
+            for (String v : newValues) {
+                if (!isValidValue(v)) {
+                    throw new ProtocolException(format(
+                            "Bad header-value for header-name: '%s'", key));
+                }
+            }
+            String k = key.toLowerCase(Locale.US);
+            cookedHeaders.merge(k, newValues,
+                    (v1, v2) -> {
+                        if (v1 == null) {
+                            ArrayList<String> newV = new ArrayList<>();
+                            newV.addAll(v2);
+                            return newV;
+                        } else {
+                            v1.addAll(v2);
+                            return v1;
+                        }
+                    });
+        }
+        return cookedHeaders;
+    }
+
+    int getContentLength() throws IOException {
+        return (int) firstValueAsLong("Content-Length").orElse(-1);
+    }
+
+    @Override
+    public Optional<String> firstValue(String name) {
+        return delegate.firstValue(name);
+    }
+
+    @Override
+    public OptionalLong firstValueAsLong(String name) {
+        return delegate.firstValueAsLong(name);
+    }
+
+    @Override
+    public List<String> allValues(String name) {
+        return delegate.allValues(name);
+    }
+
+    @Override
+    public Map<String, List<String>> map() {
+        return delegate.map();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseProcessors.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Flow;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Utils;
+import jdk.incubator.http.internal.common.Log;
+
+class ResponseProcessors {
+
+    abstract static class AbstractProcessor<T>
+        implements HttpResponse.BodyProcessor<T>
+    {
+        HttpClientImpl client;
+
+        synchronized void setClient(HttpClientImpl client) {
+            this.client = client;
+        }
+
+        synchronized HttpClientImpl getClient() {
+            return client;
+        }
+    }
+
+    static class ConsumerProcessor extends AbstractProcessor<Void> {
+        private final Consumer<Optional<byte[]>> consumer;
+        private Flow.Subscription subscription;
+        private final CompletableFuture<Void> result = new MinimalFuture<>();
+
+        ConsumerProcessor(Consumer<Optional<byte[]>> consumer) {
+            this.consumer = consumer;
+        }
+
+        @Override
+        public CompletionStage<Void> getBody() {
+            return result;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            this.subscription = subscription;
+            subscription.request(1);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            byte[] buf = new byte[item.remaining()];
+            item.get(buf);
+            consumer.accept(Optional.of(buf));
+            subscription.request(1);
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            result.completeExceptionally(throwable);
+        }
+
+        @Override
+        public void onComplete() {
+            consumer.accept(Optional.empty());
+            result.complete(null);
+        }
+
+    }
+
+    static class PathProcessor extends AbstractProcessor<Path> {
+
+        private final Path file;
+        private final CompletableFuture<Path> result = new MinimalFuture<>();
+
+        private Flow.Subscription subscription;
+        private FileChannel out;
+        private final OpenOption[] options;
+
+        PathProcessor(Path file, OpenOption... options) {
+            this.file = file;
+            this.options = options;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            this.subscription = subscription;
+            try {
+                out = FileChannel.open(file, options);
+            } catch (IOException e) {
+                result.completeExceptionally(e);
+                subscription.cancel();
+                return;
+            }
+            subscription.request(1);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            try {
+                out.write(item);
+            } catch (IOException ex) {
+                Utils.close(out);
+                subscription.cancel();
+                result.completeExceptionally(ex);
+            }
+            subscription.request(1);
+        }
+
+        @Override
+        public void onError(Throwable e) {
+            result.completeExceptionally(e);
+            Utils.close(out);
+        }
+
+        @Override
+        public void onComplete() {
+            Utils.close(out);
+            result.complete(file);
+        }
+
+        @Override
+        public CompletionStage<Path> getBody() {
+            return result;
+        }
+    }
+
+    static class ByteArrayProcessor<T> extends AbstractProcessor<T> {
+        private final Function<byte[], T> finisher;
+        private final CompletableFuture<T> result = new MinimalFuture<>();
+        private final List<ByteBuffer> received = new ArrayList<>();
+
+        private Flow.Subscription subscription;
+
+        ByteArrayProcessor(Function<byte[],T> finisher) {
+            this.finisher = finisher;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            if (this.subscription != null) {
+                subscription.cancel();
+                return;
+            }
+            this.subscription = subscription;
+            // We can handle whatever you've got
+            subscription.request(Long.MAX_VALUE);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            // incoming buffers are allocated by http client internally,
+            // and won't be used anywhere except this place.
+            // So it's free simply to store them for further processing.
+            if(item.hasRemaining()) {
+                received.add(item);
+            }
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            received.clear();
+            result.completeExceptionally(throwable);
+        }
+
+        static private byte[] join(List<ByteBuffer> bytes) {
+            int size = Utils.remaining(bytes);
+            byte[] res = new byte[size];
+            int from = 0;
+            for (ByteBuffer b : bytes) {
+                int l = b.remaining();
+                b.get(res, from, l);
+                from += l;
+            }
+            return res;
+        }
+
+        @Override
+        public void onComplete() {
+            try {
+                result.complete(finisher.apply(join(received)));
+                received.clear();
+            } catch (IllegalArgumentException e) {
+                result.completeExceptionally(e);
+            }
+        }
+
+        @Override
+        public CompletionStage<T> getBody() {
+            return result;
+        }
+    }
+
+    static class MultiProcessorImpl<V> implements HttpResponse.MultiProcessor<MultiMapResult<V>,V> {
+        private final MultiMapResult<V> results;
+        private final Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> pushHandler;
+        private final boolean completion; // aggregate completes on last PP received or overall completion
+
+        MultiProcessorImpl(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> pushHandler, boolean completion) {
+            this.results = new MultiMapResult<V>(new ConcurrentHashMap<>());
+            this.pushHandler = pushHandler;
+            this.completion = completion;
+        }
+
+        @Override
+        public Optional<HttpResponse.BodyHandler<V>> onRequest(HttpRequest request) {
+            return pushHandler.apply(request);
+        }
+
+        @Override
+        public void onResponse(HttpResponse<V> response) {
+            results.put(response.request(), CompletableFuture.completedFuture(response));
+        }
+
+        @Override
+        public void onError(HttpRequest request, Throwable t) {
+            results.put(request, CompletableFuture.failedFuture(t));
+        }
+
+        @Override
+        public CompletableFuture<MultiMapResult<V>> completion(
+                CompletableFuture<Void> onComplete, CompletableFuture<Void> onFinalPushPromise) {
+            if (completion)
+                return onComplete.thenApply((ignored)-> results);
+            else
+                return onFinalPushPromise.thenApply((ignored) -> results);
+        }
+    }
+
+    static class MultiFile {
+
+        final Path pathRoot;
+
+        MultiFile(Path destination) {
+            if (!destination.toFile().isDirectory())
+                throw new UncheckedIOException(new IOException("destination is not a directory"));
+            pathRoot = destination;
+        }
+
+        Optional<HttpResponse.BodyHandler<Path>> handlePush(HttpRequest request) {
+            final URI uri = request.uri();
+            String path = uri.getPath();
+            while (path.startsWith("/"))
+                path = path.substring(1);
+            Path p = pathRoot.resolve(path);
+            if (Log.trace()) {
+                Log.logTrace("Creating file body processor for URI={0}, path={1}",
+                             uri, p);
+            }
+            try {
+                Files.createDirectories(p.getParent());
+            } catch (IOException ex) {
+                throw new UncheckedIOException(ex);
+            }
+
+            final HttpResponse.BodyHandler<Path> proc =
+                 HttpResponse.BodyHandler.asFile(p);
+
+            return Optional.of(proc);
+        }
+    }
+
+    /**
+     * Currently this consumes all of the data and ignores it
+     */
+    static class NullProcessor<T> extends AbstractProcessor<T> {
+
+        Flow.Subscription subscription;
+        final CompletableFuture<T> cf = new MinimalFuture<>();
+        final Optional<T> result;
+
+        NullProcessor(Optional<T> result) {
+            this.result = result;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            this.subscription = subscription;
+            subscription.request(Long.MAX_VALUE);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            // TODO: check whether this should consume the buffer, as in:
+            item.position(item.limit());
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            cf.completeExceptionally(throwable);
+        }
+
+        @Override
+        public void onComplete() {
+            if (result.isPresent()) {
+                cf.complete(result.get());
+            } else {
+                cf.complete(null);
+            }
+        }
+
+        @Override
+        public CompletionStage<T> getBody() {
+            return cf;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLParameters;
+import jdk.incubator.http.SSLDelegate.WrapperResult;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.MinimalFuture;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * An SSL connection built on a Plain TCP connection.
+ */
+class SSLConnection extends HttpConnection {
+
+    PlainHttpConnection delegate;
+    SSLDelegate sslDelegate;
+    final String[] alpn;
+
+    @Override
+    public CompletableFuture<Void> connectAsync() {
+        return delegate.connectAsync()
+                .thenCompose((Void v) -> {
+                    CompletableFuture<Void> cf = new MinimalFuture<>();
+                    try {
+                        this.sslDelegate = new SSLDelegate(delegate.channel(),
+                                                           client,
+                                                           alpn);
+                        cf.complete(null);
+                    } catch (IOException e) {
+                        cf.completeExceptionally(e);
+                    }
+                    return cf;
+                });
+    }
+
+    @Override
+    public void connect() throws IOException {
+        delegate.connect();
+        this.sslDelegate = new SSLDelegate(delegate.channel(), client, alpn);
+    }
+
+    SSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) {
+        super(addr, client);
+        this.alpn = ap;
+        delegate = new PlainHttpConnection(addr, client);
+    }
+
+    @Override
+    SSLParameters sslParameters() {
+        return sslDelegate.getSSLParameters();
+    }
+
+    @Override
+    public String toString() {
+        return "SSLConnection: " + super.toString();
+    }
+
+    private static long countBytes(ByteBuffer[] buffers, int start, int length) {
+        long c = 0;
+        for (int i=0; i<length; i++) {
+            c+= buffers[start+i].remaining();
+        }
+        return c;
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return ConnectionPool.cacheKey(address, null);
+    }
+
+    @Override
+    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
+        //debugPrint("Send", buffers, start, number);
+        long l = countBytes(buffers, start, number);
+        WrapperResult r = sslDelegate.sendData(buffers, start, number);
+        if (r.result.getStatus() == Status.CLOSED) {
+            if (l > 0) {
+                throw new IOException("SSLHttpConnection closed");
+            }
+        }
+        return l;
+    }
+
+    @Override
+    long write(ByteBuffer buffer) throws IOException {
+        //debugPrint("Send", buffer);
+        long l = buffer.remaining();
+        WrapperResult r = sslDelegate.sendData(buffer);
+        if (r.result.getStatus() == Status.CLOSED) {
+            if (l > 0) {
+                throw new IOException("SSLHttpConnection closed");
+            }
+        }
+        return l;
+    }
+
+    @Override
+    void writeAsync(ByteBufferReference[] buffers) throws IOException {
+        write(ByteBufferReference.toBuffers(buffers), 0, buffers.length);
+    }
+
+    @Override
+    void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+        write(ByteBufferReference.toBuffers(buffers), 0, buffers.length);
+    }
+
+    @Override
+    void flushAsync() throws IOException {
+        // nothing to do
+    }
+
+    @Override
+    public void close() {
+        Utils.close(delegate.channel());
+    }
+
+    @Override
+    void shutdownInput() throws IOException {
+        delegate.channel().shutdownInput();
+    }
+
+    @Override
+    void shutdownOutput() throws IOException {
+        delegate.channel().shutdownOutput();
+    }
+
+    @Override
+    protected ByteBuffer readImpl() throws IOException {
+        ByteBuffer dst = ByteBuffer.allocate(8192);
+        int n = readImpl(dst);
+        if (n > 0) {
+            return dst;
+        } else if (n == 0) {
+            return Utils.EMPTY_BYTEBUFFER;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    protected int readImpl(ByteBuffer buf) throws IOException {
+        // TODO: need to ensure that buf is big enough for application data
+        WrapperResult r = sslDelegate.recvData(buf);
+        // TODO: check for closure
+        String s = "Receive) ";
+        //debugPrint(s, r.buf);
+        if (r.result.bytesProduced() > 0) {
+            assert buf == r.buf;
+        }
+        return r.result.bytesProduced();
+    }
+
+    @Override
+    boolean connected() {
+        return delegate.connected();
+    }
+
+    @Override
+    SocketChannel channel() {
+        return delegate.channel();
+    }
+
+    @Override
+    CompletableFuture<Void> whenReceivingResponse() {
+        return delegate.whenReceivingResponse();
+    }
+
+    @Override
+    boolean isSecure() {
+        return true;
+    }
+
+    @Override
+    boolean isProxied() {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLDelegate.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.Arrays;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.*;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.Utils;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
+
+/**
+ * Implements the mechanics of SSL by managing an SSLEngine object.
+ * One of these is associated with each SSLConnection.
+ */
+class SSLDelegate {
+
+    final SSLEngine engine;
+    final EngineWrapper wrapper;
+    final Lock handshaking = new ReentrantLock();
+    final SSLParameters sslParameters;
+    final SocketChannel chan;
+    final HttpClientImpl client;
+
+    // alpn[] may be null
+    SSLDelegate(SocketChannel chan, HttpClientImpl client, String[] alpn)
+        throws IOException
+    {
+        SSLContext context = client.sslContext();
+        engine = context.createSSLEngine();
+        engine.setUseClientMode(true);
+        SSLParameters sslp = client.sslParameters()
+                                   .orElseGet(context::getSupportedSSLParameters);
+        sslParameters = Utils.copySSLParameters(sslp);
+        if (alpn != null) {
+            sslParameters.setApplicationProtocols(alpn);
+            Log.logSSL(() -> "Setting application protocols: " + Arrays.toString(alpn));
+        } else {
+            Log.logSSL("No application protocols proposed");
+        }
+        engine.setSSLParameters(sslParameters);
+        wrapper = new EngineWrapper(chan, engine);
+        this.chan = chan;
+        this.client = client;
+    }
+
+    SSLParameters getSSLParameters() {
+        return sslParameters;
+    }
+
+    private static long countBytes(ByteBuffer[] buffers, int start, int number) {
+        long c = 0;
+        for (int i=0; i<number; i++) {
+            c+= buffers[start+i].remaining();
+        }
+        return c;
+    }
+
+
+    static class WrapperResult {
+        static WrapperResult createOK() {
+            WrapperResult r = new WrapperResult();
+            r.buf = null;
+            r.result = new SSLEngineResult(Status.OK, NOT_HANDSHAKING, 0, 0);
+            return r;
+        }
+        SSLEngineResult result;
+
+        /* if passed in buffer was not big enough then the a reallocated buffer
+         * is returned here  */
+        ByteBuffer buf;
+    }
+
+    int app_buf_size;
+    int packet_buf_size;
+
+    enum BufType {
+        PACKET,
+        APPLICATION
+    }
+
+    ByteBuffer allocate (BufType type) {
+        return allocate (type, -1);
+    }
+
+    // TODO: Use buffer pool for this
+    ByteBuffer allocate (BufType type, int len) {
+        assert engine != null;
+        synchronized (this) {
+            int size;
+            if (type == BufType.PACKET) {
+                if (packet_buf_size == 0) {
+                    SSLSession sess = engine.getSession();
+                    packet_buf_size = sess.getPacketBufferSize();
+                }
+                if (len > packet_buf_size) {
+                    packet_buf_size = len;
+                }
+                size = packet_buf_size;
+            } else {
+                if (app_buf_size == 0) {
+                    SSLSession sess = engine.getSession();
+                    app_buf_size = sess.getApplicationBufferSize();
+                }
+                if (len > app_buf_size) {
+                    app_buf_size = len;
+                }
+                size = app_buf_size;
+            }
+            return ByteBuffer.allocate (size);
+        }
+    }
+
+    /* reallocates the buffer by :-
+     * 1. creating a new buffer double the size of the old one
+     * 2. putting the contents of the old buffer into the new one
+     * 3. set xx_buf_size to the new size if it was smaller than new size
+     *
+     * flip is set to true if the old buffer needs to be flipped
+     * before it is copied.
+     */
+    private ByteBuffer realloc (ByteBuffer b, boolean flip, BufType type) {
+        // TODO: there should be the linear growth, rather than exponential as
+        // we definitely know the maximum amount of space required to unwrap
+        synchronized (this) {
+            int nsize = 2 * b.capacity();
+            ByteBuffer n = allocate (type, nsize);
+            if (flip) {
+                b.flip();
+            }
+            n.put(b);
+            b = n;
+        }
+        return b;
+    }
+
+    /**
+     * This is a thin wrapper over SSLEngine and the SocketChannel, which
+     * guarantees the ordering of wraps/unwraps with respect to the underlying
+     * channel read/writes. It handles the UNDER/OVERFLOW status codes
+     * It does not handle the handshaking status codes, or the CLOSED status code
+     * though once the engine is closed, any attempt to read/write to it
+     * will get an exception.  The overall result is returned.
+     * It functions synchronously/blocking
+     */
+    class EngineWrapper {
+
+        SocketChannel chan;
+        SSLEngine engine;
+        Object wrapLock, unwrapLock;
+        ByteBuffer unwrap_src, wrap_dst;
+        boolean closed = false;
+        int u_remaining; // the number of bytes left in unwrap_src after an unwrap()
+
+        EngineWrapper (SocketChannel chan, SSLEngine engine) throws IOException {
+            this.chan = chan;
+            this.engine = engine;
+            wrapLock = new Object();
+            unwrapLock = new Object();
+            unwrap_src = allocate(BufType.PACKET);
+            wrap_dst = allocate(BufType.PACKET);
+        }
+
+        void close () throws IOException {
+        }
+
+        WrapperResult wrapAndSend(ByteBuffer src, boolean ignoreClose)
+            throws IOException
+        {
+            ByteBuffer[] buffers = new ByteBuffer[1];
+            buffers[0] = src;
+            return wrapAndSend(buffers, 0, 1, ignoreClose);
+        }
+
+        /* try to wrap and send the data in src. Handles OVERFLOW.
+         * Might block if there is an outbound blockage or if another
+         * thread is calling wrap(). Also, might not send any data
+         * if an unwrap is needed.
+         */
+        WrapperResult wrapAndSend(ByteBuffer[] src,
+                                  int offset,
+                                  int len,
+                                  boolean ignoreClose)
+            throws IOException
+        {
+            if (closed && !ignoreClose) {
+                throw new IOException ("Engine is closed");
+            }
+            Status status;
+            WrapperResult r = new WrapperResult();
+            synchronized (wrapLock) {
+                wrap_dst.clear();
+                do {
+                    r.result = engine.wrap (src, offset, len, wrap_dst);
+                    status = r.result.getStatus();
+                    if (status == Status.BUFFER_OVERFLOW) {
+                        wrap_dst = realloc (wrap_dst, true, BufType.PACKET);
+                    }
+                } while (status == Status.BUFFER_OVERFLOW);
+                if (status == Status.CLOSED && !ignoreClose) {
+                    closed = true;
+                    return r;
+                }
+                if (r.result.bytesProduced() > 0) {
+                    wrap_dst.flip();
+                    int l = wrap_dst.remaining();
+                    assert l == r.result.bytesProduced();
+                    while (l>0) {
+                        l -= chan.write (wrap_dst);
+                    }
+                }
+            }
+            return r;
+        }
+
+        /* block until a complete message is available and return it
+         * in dst, together with the Result. dst may have been re-allocated
+         * so caller should check the returned value in Result
+         * If handshaking is in progress then, possibly no data is returned
+         */
+        WrapperResult recvAndUnwrap(ByteBuffer dst) throws IOException {
+            Status status;
+            WrapperResult r = new WrapperResult();
+            r.buf = dst;
+            if (closed) {
+                throw new IOException ("Engine is closed");
+            }
+            boolean needData;
+            if (u_remaining > 0) {
+                unwrap_src.compact();
+                unwrap_src.flip();
+                needData = false;
+            } else {
+                unwrap_src.clear();
+                needData = true;
+            }
+            synchronized (unwrapLock) {
+                int x;
+                do {
+                    if (needData) {
+                        do {
+                            x = chan.read (unwrap_src);
+                        } while (x == 0);
+                        if (x == -1) {
+                            throw new IOException ("connection closed for reading");
+                        }
+                        unwrap_src.flip();
+                    }
+                    r.result = engine.unwrap (unwrap_src, r.buf);
+                    status = r.result.getStatus();
+                    if (status == Status.BUFFER_UNDERFLOW) {
+                        if (unwrap_src.limit() == unwrap_src.capacity()) {
+                            /* buffer not big enough */
+                            unwrap_src = realloc (
+                                unwrap_src, false, BufType.PACKET
+                            );
+                        } else {
+                            /* Buffer not full, just need to read more
+                             * data off the channel. Reset pointers
+                             * for reading off SocketChannel
+                             */
+                            unwrap_src.position (unwrap_src.limit());
+                            unwrap_src.limit (unwrap_src.capacity());
+                        }
+                        needData = true;
+                    } else if (status == Status.BUFFER_OVERFLOW) {
+                        r.buf = realloc (r.buf, true, BufType.APPLICATION);
+                        needData = false;
+                    } else if (status == Status.CLOSED) {
+                        closed = true;
+                        r.buf.flip();
+                        return r;
+                    }
+                } while (status != Status.OK);
+            }
+            u_remaining = unwrap_src.remaining();
+            return r;
+        }
+    }
+
+    WrapperResult sendData (ByteBuffer src) throws IOException {
+        ByteBuffer[] buffers = new ByteBuffer[1];
+        buffers[0] = src;
+        return sendData(buffers, 0, 1);
+    }
+
+    /**
+     * send the data in the given ByteBuffer. If a handshake is needed
+     * then this is handled within this method. When this call returns,
+     * all of the given user data has been sent and any handshake has been
+     * completed. Caller should check if engine has been closed.
+     */
+    WrapperResult sendData (ByteBuffer[] src, int offset, int len) throws IOException {
+        WrapperResult r = WrapperResult.createOK();
+        while (countBytes(src, offset, len) > 0) {
+            r = wrapper.wrapAndSend(src, offset, len, false);
+            Status status = r.result.getStatus();
+            if (status == Status.CLOSED) {
+                doClosure ();
+                return r;
+            }
+            HandshakeStatus hs_status = r.result.getHandshakeStatus();
+            if (hs_status != HandshakeStatus.FINISHED &&
+                hs_status != HandshakeStatus.NOT_HANDSHAKING)
+            {
+                doHandshake(hs_status);
+            }
+        }
+        return r;
+    }
+
+    /**
+     * read data thru the engine into the given ByteBuffer. If the
+     * given buffer was not large enough, a new one is allocated
+     * and returned. This call handles handshaking automatically.
+     * Caller should check if engine has been closed.
+     */
+    WrapperResult recvData (ByteBuffer dst) throws IOException {
+        /* we wait until some user data arrives */
+        int mark = dst.position();
+        WrapperResult r = null;
+        int pos = dst.position();
+        while (dst.position() == pos) {
+            r = wrapper.recvAndUnwrap (dst);
+            dst = (r.buf != dst) ? r.buf: dst;
+            Status status = r.result.getStatus();
+            if (status == Status.CLOSED) {
+                doClosure ();
+                return r;
+            }
+
+            HandshakeStatus hs_status = r.result.getHandshakeStatus();
+            if (hs_status != HandshakeStatus.FINISHED &&
+                hs_status != HandshakeStatus.NOT_HANDSHAKING)
+            {
+                doHandshake (hs_status);
+            }
+        }
+        Utils.flipToMark(dst, mark);
+        return r;
+    }
+
+    /* we've received a close notify. Need to call wrap to send
+     * the response
+     */
+    void doClosure () throws IOException {
+        try {
+            handshaking.lock();
+            ByteBuffer tmp = allocate(BufType.APPLICATION);
+            WrapperResult r;
+            do {
+                tmp.clear();
+                tmp.flip ();
+                r = wrapper.wrapAndSend(tmp, true);
+            } while (r.result.getStatus() != Status.CLOSED);
+        } finally {
+            handshaking.unlock();
+        }
+    }
+
+    /* do the (complete) handshake after acquiring the handshake lock.
+     * If two threads call this at the same time, then we depend
+     * on the wrapper methods being idempotent. eg. if wrapAndSend()
+     * is called with no data to send then there must be no problem
+     */
+    @SuppressWarnings("fallthrough")
+    void doHandshake (HandshakeStatus hs_status) throws IOException {
+        boolean wasBlocking = false;
+        try {
+            wasBlocking = chan.isBlocking();
+            handshaking.lock();
+            chan.configureBlocking(true);
+            ByteBuffer tmp = allocate(BufType.APPLICATION);
+            while (hs_status != HandshakeStatus.FINISHED &&
+                   hs_status != HandshakeStatus.NOT_HANDSHAKING)
+            {
+                WrapperResult r = null;
+                switch (hs_status) {
+                    case NEED_TASK:
+                        Runnable task;
+                        while ((task = engine.getDelegatedTask()) != null) {
+                            /* run in current thread, because we are already
+                             * running an external Executor
+                             */
+                            task.run();
+                        }
+                        /* fall thru - call wrap again */
+                    case NEED_WRAP:
+                        tmp.clear();
+                        tmp.flip();
+                        r = wrapper.wrapAndSend(tmp, false);
+                        break;
+
+                    case NEED_UNWRAP:
+                        tmp.clear();
+                        r = wrapper.recvAndUnwrap (tmp);
+                        if (r.buf != tmp) {
+                            tmp = r.buf;
+                        }
+                        assert tmp.position() == 0;
+                        break;
+                }
+                hs_status = r.result.getHandshakeStatus();
+            }
+            Log.logSSL(getSessionInfo());
+            if (!wasBlocking) {
+                chan.configureBlocking(false);
+            }
+        } finally {
+            handshaking.unlock();
+        }
+    }
+
+    static void printParams(SSLParameters p) {
+        System.out.println("SSLParameters:");
+        if (p == null) {
+            System.out.println("Null params");
+            return;
+        }
+        for (String cipher : p.getCipherSuites()) {
+                System.out.printf("cipher: %s\n", cipher);
+        }
+        for (String approto : p.getApplicationProtocols()) {
+                System.out.printf("application protocol: %s\n", approto);
+        }
+        for (String protocol : p.getProtocols()) {
+                System.out.printf("protocol: %s\n", protocol);
+        }
+        if (p.getServerNames() != null) {
+            for (SNIServerName sname : p.getServerNames()) {
+                System.out.printf("server name: %s\n", sname.toString());
+            }
+        }
+    }
+
+    String getSessionInfo() {
+        StringBuilder sb = new StringBuilder();
+        String application = engine.getApplicationProtocol();
+        SSLSession sess = engine.getSession();
+        String cipher = sess.getCipherSuite();
+        String protocol = sess.getProtocol();
+        sb.append("Handshake complete alpn: ")
+                .append(application)
+                .append(", Cipher: ")
+                .append(cipher)
+                .append(", Protocol: ")
+                .append(protocol);
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLParameters;
+import jdk.incubator.http.SSLDelegate.WrapperResult;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+/**
+ * An SSL tunnel built on a Plain (CONNECT) TCP tunnel.
+ */
+class SSLTunnelConnection extends HttpConnection {
+
+    final PlainTunnelingConnection delegate;
+    protected SSLDelegate sslDelegate;
+    private volatile boolean connected;
+
+    @Override
+    public void connect() throws IOException, InterruptedException {
+        delegate.connect();
+        this.sslDelegate = new SSLDelegate(delegate.channel(), client, null);
+        connected = true;
+    }
+
+    @Override
+    boolean connected() {
+        return connected && delegate.connected();
+    }
+
+    @Override
+    public CompletableFuture<Void> connectAsync() {
+        return delegate.connectAsync()
+            .thenAccept((Void v) -> {
+                try {
+                    // can this block?
+                    this.sslDelegate = new SSLDelegate(delegate.channel(),
+                                                       client,
+                                                       null);
+                    connected = true;
+                } catch (IOException e) {
+                    throw new UncheckedIOException(e);
+                }
+            });
+    }
+
+    SSLTunnelConnection(InetSocketAddress addr,
+                        HttpClientImpl client,
+                        InetSocketAddress proxy)
+    {
+        super(addr, client);
+        delegate = new PlainTunnelingConnection(addr, proxy, client);
+    }
+
+    @Override
+    SSLParameters sslParameters() {
+        return sslDelegate.getSSLParameters();
+    }
+
+    @Override
+    public String toString() {
+        return "SSLTunnelConnection: " + super.toString();
+    }
+
+    private static long countBytes(ByteBuffer[] buffers, int start, int number) {
+        long c = 0;
+        for (int i=0; i<number; i++) {
+            c+= buffers[start+i].remaining();
+        }
+        return c;
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return ConnectionPool.cacheKey(address, delegate.proxyAddr);
+    }
+
+    @Override
+    long write(ByteBuffer[] buffers, int start, int number) throws IOException {
+        //debugPrint("Send", buffers, start, number);
+        long l = countBytes(buffers, start, number);
+        WrapperResult r = sslDelegate.sendData(buffers, start, number);
+        if (r.result.getStatus() == Status.CLOSED) {
+            if (l > 0) {
+                throw new IOException("SSLHttpConnection closed");
+            }
+        }
+        return l;
+    }
+
+    @Override
+    long write(ByteBuffer buffer) throws IOException {
+        //debugPrint("Send", buffer);
+        long l = buffer.remaining();
+        WrapperResult r = sslDelegate.sendData(buffer);
+        if (r.result.getStatus() == Status.CLOSED) {
+            if (l > 0) {
+                throw new IOException("SSLHttpConnection closed");
+            }
+        }
+        return l;
+    }
+
+    @Override
+    void writeAsync(ByteBufferReference[] buffers) throws IOException {
+        write(ByteBufferReference.toBuffers(buffers), 0, buffers.length);
+    }
+
+    @Override
+    void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+        write(ByteBufferReference.toBuffers(buffers), 0, buffers.length);
+    }
+
+    @Override
+    void flushAsync() throws IOException {
+        // nothing to do
+    }
+
+    @Override
+    public void close() {
+        Utils.close(delegate.channel());
+    }
+
+    @Override
+    void shutdownInput() throws IOException {
+        delegate.channel().shutdownInput();
+    }
+
+    @Override
+    void shutdownOutput() throws IOException {
+        delegate.channel().shutdownOutput();
+    }
+
+    @Override
+    protected ByteBuffer readImpl() throws IOException {
+        return sslDelegate.recvData(Utils.EMPTY_BYTEBUFFER).buf; // fix this, make the read normal
+    }
+
+    @Override
+    protected int readImpl(ByteBuffer buf) throws IOException {
+        WrapperResult r = sslDelegate.recvData(buf);
+        // TODO: check for closure
+        String s = "Receive) ";
+        //debugPrint(s, r.buf);
+        if (r.result.bytesProduced() > 0) {
+            assert buf == r.buf;
+        }
+        return r.result.bytesProduced();
+    }
+
+    @Override
+    SocketChannel channel() {
+        return delegate.channel();
+    }
+
+    @Override
+    CompletableFuture<Void> whenReceivingResponse() {
+        return delegate.whenReceivingResponse();
+    }
+
+    @Override
+    boolean isSecure() {
+        return true;
+    }
+
+    @Override
+    boolean isProxied() {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Stream.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,955 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Flow;
+import java.util.concurrent.Flow.Subscription;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import jdk.incubator.http.internal.common.*;
+import jdk.incubator.http.internal.frame.*;
+import jdk.incubator.http.internal.hpack.DecodingCallback;
+
+/**
+ * Http/2 Stream handling.
+ *
+ * REQUESTS
+ *
+ * sendHeadersOnly() -- assembles HEADERS frame and puts on connection outbound Q
+ *
+ * sendRequest() -- sendHeadersOnly() + sendBody()
+ *
+ * sendBody() -- in calling thread: obeys all flow control (so may block)
+ *               obtains data from request body processor and places on connection
+ *               outbound Q.
+ *
+ * sendBodyAsync() -- calls sendBody() in an executor thread.
+ *
+ * sendHeadersAsync() -- calls sendHeadersOnly() which does not block
+ *
+ * sendRequestAsync() -- calls sendRequest() in an executor thread
+ *
+ * RESPONSES
+ *
+ * Multiple responses can be received per request. Responses are queued up on
+ * a LinkedList of CF<HttpResponse> and the the first one on the list is completed
+ * with the next response
+ *
+ * getResponseAsync() -- queries list of response CFs and returns first one
+ *               if one exists. Otherwise, creates one and adds it to list
+ *               and returns it. Completion is achieved through the
+ *               incoming() upcall from connection reader thread.
+ *
+ * getResponse() -- calls getResponseAsync() and waits for CF to complete
+ *
+ * responseBody() -- in calling thread: blocks for incoming DATA frames on
+ *               stream inputQ. Obeys remote and local flow control so may block.
+ *               Calls user response body processor with data buffers.
+ *
+ * responseBodyAsync() -- calls responseBody() in an executor thread.
+ *
+ * incoming() -- entry point called from connection reader thread. Frames are
+ *               either handled immediately without blocking or for data frames
+ *               placed on the stream's inputQ which is consumed by the stream's
+ *               reader thread.
+ *
+ * PushedStream sub class
+ * ======================
+ * Sending side methods are not used because the request comes from a PUSH_PROMISE
+ * frame sent by the server. When a PUSH_PROMISE is received the PushedStream
+ * is created. PushedStream does not use responseCF list as there can be only
+ * one response. The CF is created when the object created and when the response
+ * HEADERS frame is received the object is completed.
+ */
+class Stream<T> extends ExchangeImpl<T> {
+
+    final Queue<Http2Frame> inputQ;
+
+    /**
+     * This stream's identifier. Assigned lazily by the HTTP2Connection before
+     * the stream's first frame is sent.
+     */
+    protected volatile int streamid;
+
+    long responseContentLen = -1;
+    long responseBytesProcessed = 0;
+    long requestContentLen;
+
+    final Http2Connection connection;
+    HttpClientImpl client;
+    final HttpRequestImpl request;
+    final DecodingCallback rspHeadersConsumer;
+    HttpHeadersImpl responseHeaders;
+    final HttpHeadersImpl requestHeaders;
+    final HttpHeadersImpl requestPseudoHeaders;
+    HttpResponse.BodyProcessor<T> responseProcessor;
+    final HttpRequest.BodyProcessor requestProcessor;
+    volatile int responseCode;
+    volatile Response response;
+    volatile CompletableFuture<Response> responseCF;
+    final AbstractPushPublisher<ByteBuffer> publisher;
+    final CompletableFuture<Void> requestBodyCF = new MinimalFuture<>();
+
+    /** True if END_STREAM has been seen in a frame received on this stream. */
+    private volatile boolean remotelyClosed;
+    private volatile boolean closed;
+    private volatile boolean endStreamSent;
+
+    // state flags
+    boolean requestSent, responseReceived, responseHeadersReceived;
+
+    /**
+     * A reference to this Stream's connection Send Window controller. The
+     * stream MUST acquire the appropriate amount of Send Window before
+     * sending any data. Will be null for PushStreams, as they cannot send data.
+     */
+    private final WindowController windowController;
+    private final WindowUpdateSender windowUpdater;
+
+    @Override
+    HttpConnection connection() {
+        return connection.connection;
+    }
+
+    @Override
+    CompletableFuture<T> readBodyAsync(HttpResponse.BodyHandler<T> handler,
+                                       boolean returnToCache,
+                                       Executor executor)
+    {
+        Log.logTrace("Reading body on stream {0}", streamid);
+        responseProcessor = handler.apply(responseCode, responseHeaders);
+        setClientForResponse(responseProcessor);
+        publisher.subscribe(responseProcessor);
+        CompletableFuture<T> cf = receiveData(executor);
+
+        PushGroup<?,?> pg = exchange.getPushGroup();
+        if (pg != null) {
+            // if an error occurs make sure it is recorded in the PushGroup
+            cf = cf.whenComplete((t,e) -> pg.pushError(e));
+        }
+        return cf;
+    }
+
+    @Override
+    T readBody(HttpResponse.BodyHandler<T> handler, boolean returnToCache)
+        throws IOException
+    {
+        CompletableFuture<T> cf = readBodyAsync(handler,
+                                                returnToCache,
+                                                this::executeInline);
+        try {
+            return cf.join();
+        } catch (CompletionException e) {
+            throw Utils.getIOException(e);
+        }
+    }
+
+    void executeInline(Runnable r) {
+        r.run();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("streamid: ")
+                .append(streamid);
+        return sb.toString();
+    }
+
+    // pushes entire response body into response processor
+    // blocking when required by local or remote flow control
+    CompletableFuture<T> receiveData(Executor executor) {
+        CompletableFuture<T> cf = responseProcessor
+                .getBody()
+                .toCompletableFuture();
+
+        executor.execute(() -> {
+            Http2Frame frame;
+            DataFrame df = null;
+            try {
+                if (!endStreamReceived()) {
+                    do {
+                        frame = inputQ.take();
+                        if (frame instanceof ResetFrame) {
+                            handleReset((ResetFrame)frame);
+                            continue;
+                        } else if (!(frame instanceof DataFrame)) {
+                            assert false;
+                            continue;
+                        }
+                        df = (DataFrame) frame;
+                        // RFC 7540 6.1:
+                        // The entire DATA frame payload is included in flow control,
+                        // including the Pad Length and Padding fields if present
+                        int len = df.payloadLength();
+                        ByteBufferReference[] buffers = df.getData();
+                        for (ByteBufferReference b : buffers) {
+                            publisher.acceptData(Optional.of(b.get()));
+                        }
+                        connection.windowUpdater.update(len);
+                        if (df.getFlag(DataFrame.END_STREAM)) {
+                            break;
+                        }
+                        // Don't send window update on a stream which is
+                        // closed or half closed.
+                        windowUpdater.update(len);
+                    } while (true);
+                    setEndStreamReceived();
+                }
+                publisher.acceptData(Optional.empty());
+            } catch (Throwable e) {
+                Log.logTrace("receiveData: {0}", e.toString());
+                e.printStackTrace();
+                cf.completeExceptionally(e);
+                publisher.acceptError(e);
+            }
+        });
+        return cf;
+    }
+
+    @Override
+    void sendBody() throws IOException, InterruptedException {
+        sendBodyImpl();
+    }
+
+    @SuppressWarnings("unchecked")
+    Stream(HttpClientImpl client,
+           Http2Connection connection,
+           Exchange<T> e,
+           WindowController windowController)
+    {
+        super(e);
+        this.client = client;
+        this.connection = connection;
+        this.windowController = windowController;
+        this.request = e.request();
+        this.requestProcessor = request.requestProcessor;
+        responseHeaders = new HttpHeadersImpl();
+        requestHeaders = new HttpHeadersImpl();
+        rspHeadersConsumer = (name, value) -> {
+            responseHeaders.addHeader(name.toString(), value.toString());
+            if (Log.headers() && Log.trace()) {
+                Log.logTrace("RECEIVED HEADER (streamid={0}): {1}: {2}",
+                             streamid, name, value);
+            }
+        };
+        this.requestPseudoHeaders = new HttpHeadersImpl();
+        // NEW
+        this.inputQ = new Queue<>();
+        this.publisher = new BlockingPushPublisher<>();
+        this.windowUpdater = new StreamWindowUpdateSender(connection);
+    }
+
+    /**
+     * Entry point from Http2Connection reader thread.
+     *
+     * Data frames will be removed by response body thread.
+     */
+    void incoming(Http2Frame frame) throws IOException {
+        if ((frame instanceof HeaderFrame)) {
+            HeaderFrame hframe = (HeaderFrame)frame;
+            if (hframe.endHeaders()) {
+                Log.logTrace("handling response (streamid={0})", streamid);
+                handleResponse();
+                if (hframe.getFlag(HeaderFrame.END_STREAM)) {
+                    inputQ.put(new DataFrame(streamid, DataFrame.END_STREAM, new ByteBufferReference[0]));
+                }
+            }
+        } else if (frame instanceof DataFrame) {
+            inputQ.put(frame);
+        } else {
+            otherFrame(frame);
+        }
+    }
+
+    void otherFrame(Http2Frame frame) throws IOException {
+        switch (frame.type()) {
+            case WindowUpdateFrame.TYPE:
+                incoming_windowUpdate((WindowUpdateFrame) frame);
+                break;
+            case ResetFrame.TYPE:
+                incoming_reset((ResetFrame) frame);
+                break;
+            case PriorityFrame.TYPE:
+                incoming_priority((PriorityFrame) frame);
+                break;
+            default:
+                String msg = "Unexpected frame: " + frame.toString();
+                throw new IOException(msg);
+        }
+    }
+
+    // The Hpack decoder decodes into one of these consumers of name,value pairs
+
+    DecodingCallback rspHeadersConsumer() {
+        return rspHeadersConsumer;
+    }
+
+    protected void handleResponse() throws IOException {
+        synchronized(this) {
+            responseHeadersReceived = true;
+        }
+        HttpConnection c = connection.connection; // TODO: improve
+        responseCode = (int)responseHeaders
+                .firstValueAsLong(":status")
+                .orElseThrow(() -> new IOException("no statuscode in response"));
+
+        response = new Response(
+                request, exchange, responseHeaders,
+                responseCode, HttpClient.Version.HTTP_2);
+
+        this.responseContentLen = responseHeaders
+                .firstValueAsLong("content-length")
+                .orElse(-1L);
+
+        if (Log.headers()) {
+            StringBuilder sb = new StringBuilder("RESPONSE HEADERS:\n");
+            Log.dumpHeaders(sb, "    ", responseHeaders);
+            Log.logHeaders(sb.toString());
+        }
+
+        completeResponse(response);
+    }
+
+    void incoming_reset(ResetFrame frame) throws IOException {
+        Log.logTrace("Received RST_STREAM on stream {0}", streamid);
+        if (endStreamReceived()) {
+            Log.logTrace("Ignoring RST_STREAM frame received on remotely closed stream {0}", streamid);
+        } else if (closed) {
+            Log.logTrace("Ignoring RST_STREAM frame received on closed stream {0}", streamid);
+        } else {
+            boolean pushedToQueue = false;
+            synchronized(this) {
+                // if the response headers are not yet
+                // received, or the inputQueue is closed, handle reset directly.
+                // Otherwise, put it in the input queue in order to read all
+                // pending data frames first. Indeed, a server may send
+                // RST_STREAM after sending END_STREAM, in which case we should
+                // ignore it. However, we won't know if we have received END_STREAM
+                // or not until all pending data frames are read.
+                // Because the inputQ will not be read until the response
+                // headers are received, and because response headers won't be
+                // sent if the server sent RST_STREAM, then we must handle
+                // reset here directly unless responseHeadersReceived is true.
+                pushedToQueue = !closed && responseHeadersReceived && inputQ.tryPut(frame);
+            }
+            if (!pushedToQueue) {
+                // RST_STREAM was not pushed to the queue: handle it.
+                try {
+                    handleReset(frame);
+                } catch (IOException io) {
+                    completeResponseExceptionally(io);
+                }
+            } else {
+                // RST_STREAM was pushed to the queue. It will be handled by
+                // asyncReceive after all pending data frames have been
+                // processed.
+                Log.logTrace("RST_STREAM pushed in queue for stream {0}", streamid);
+            }
+        }
+    }
+
+    void handleReset(ResetFrame frame) throws IOException {
+        Log.logTrace("Handling RST_STREAM on stream {0}", streamid);
+        if (!closed) {
+            close();
+            int error = frame.getErrorCode();
+            throw new IOException(ErrorFrame.stringForCode(error));
+        } else {
+            Log.logTrace("Ignoring RST_STREAM frame received on closed stream {0}", streamid);
+        }
+    }
+
+    void incoming_priority(PriorityFrame frame) {
+        // TODO: implement priority
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    private void incoming_windowUpdate(WindowUpdateFrame frame)
+        throws IOException
+    {
+        int amount = frame.getUpdate();
+        if (amount <= 0) {
+            Log.logTrace("Resetting stream: {0} %d, Window Update amount: %d\n",
+                         streamid, streamid, amount);
+            connection.resetStream(streamid, ResetFrame.FLOW_CONTROL_ERROR);
+        } else {
+            assert streamid != 0;
+            boolean success = windowController.increaseStreamWindow(amount, streamid);
+            if (!success) {  // overflow
+                connection.resetStream(streamid, ResetFrame.FLOW_CONTROL_ERROR);
+            }
+        }
+    }
+
+    void incoming_pushPromise(HttpRequestImpl pushReq,
+                              PushedStream<?,T> pushStream)
+        throws IOException
+    {
+        if (Log.requests()) {
+            Log.logRequest("PUSH_PROMISE: " + pushReq.toString());
+        }
+        PushGroup<?,T> pushGroup = exchange.getPushGroup();
+        if (pushGroup == null || pushGroup.noMorePushes()) {
+            cancelImpl(new IllegalStateException("unexpected push promise"
+                + " on stream " + streamid));
+        }
+
+        HttpResponse.MultiProcessor<?,T> proc = pushGroup.processor();
+
+        CompletableFuture<HttpResponse<T>> cf = pushStream.responseCF();
+
+        Optional<HttpResponse.BodyHandler<T>> bpOpt = proc.onRequest(
+                pushReq);
+
+        if (!bpOpt.isPresent()) {
+            IOException ex = new IOException("Stream "
+                 + streamid + " cancelled by user");
+            if (Log.trace()) {
+                Log.logTrace("No body processor for {0}: {1}", pushReq,
+                            ex.getMessage());
+            }
+            pushStream.cancelImpl(ex);
+            cf.completeExceptionally(ex);
+            return;
+        }
+
+        pushGroup.addPush();
+        pushStream.requestSent();
+        pushStream.setPushHandler(bpOpt.get());
+        // setup housekeeping for when the push is received
+        // TODO: deal with ignoring of CF anti-pattern
+        cf.whenComplete((HttpResponse<T> resp, Throwable t) -> {
+            if (Log.trace()) {
+                Log.logTrace("Push completed on stream {0} for {1}{2}",
+                             pushStream.streamid, resp,
+                             ((t==null) ? "": " with exception " + t));
+            }
+            if (t != null) {
+                pushGroup.pushError(t);
+                proc.onError(pushReq, t);
+            } else {
+                proc.onResponse(resp);
+            }
+            pushGroup.pushCompleted();
+        });
+
+    }
+
+    private OutgoingHeaders<Stream<T>> headerFrame(long contentLength) {
+        HttpHeadersImpl h = request.getSystemHeaders();
+        if (contentLength > 0) {
+            h.setHeader("content-length", Long.toString(contentLength));
+        }
+        setPseudoHeaderFields();
+        OutgoingHeaders<Stream<T>> f = new OutgoingHeaders<>(h, request.getUserHeaders(), this);
+        if (contentLength == 0) {
+            f.setFlag(HeadersFrame.END_STREAM);
+            endStreamSent = true;
+        }
+        return f;
+    }
+
+    private void setPseudoHeaderFields() {
+        HttpHeadersImpl hdrs = requestPseudoHeaders;
+        String method = request.method();
+        hdrs.setHeader(":method", method);
+        URI uri = request.uri();
+        hdrs.setHeader(":scheme", uri.getScheme());
+        // TODO: userinfo deprecated. Needs to be removed
+        hdrs.setHeader(":authority", uri.getAuthority());
+        // TODO: ensure header names beginning with : not in user headers
+        String query = uri.getQuery();
+        String path = uri.getPath();
+        if (path == null || path.isEmpty()) {
+            if (method.equalsIgnoreCase("OPTIONS")) {
+                path = "*";
+            } else {
+                path = "/";
+            }
+        }
+        if (query != null) {
+            path += "?" + query;
+        }
+        hdrs.setHeader(":path", path);
+    }
+
+    HttpHeadersImpl getRequestPseudoHeaders() {
+        return requestPseudoHeaders;
+    }
+
+    @Override
+    Response getResponse() throws IOException {
+        try {
+            if (request.duration() != null) {
+                Log.logTrace("Waiting for response (streamid={0}, timeout={1}ms)",
+                             streamid,
+                             request.duration().toMillis());
+                return getResponseAsync(null).get(
+                        request.duration().toMillis(), TimeUnit.MILLISECONDS);
+            } else {
+                Log.logTrace("Waiting for response (streamid={0})", streamid);
+                return getResponseAsync(null).join();
+            }
+        } catch (TimeoutException e) {
+            Log.logTrace("Response timeout (streamid={0})", streamid);
+            throw new HttpTimeoutException("Response timed out");
+        } catch (InterruptedException | ExecutionException | CompletionException e) {
+            Throwable t = e.getCause();
+            Log.logTrace("Response failed (streamid={0}): {1}", streamid, t);
+            if (t instanceof IOException) {
+                throw (IOException)t;
+            }
+            throw new IOException(e);
+        } finally {
+            Log.logTrace("Got response or failed (streamid={0})", streamid);
+        }
+    }
+
+    /** Sets endStreamReceived. Should be called only once. */
+    void setEndStreamReceived() {
+        assert remotelyClosed == false: "Unexpected endStream already set";
+        remotelyClosed = true;
+        responseReceived();
+    }
+
+    /** Tells whether, or not, the END_STREAM Flag has been seen in any frame
+     *  received on this stream. */
+    private boolean endStreamReceived() {
+        return remotelyClosed;
+    }
+
+    @Override
+    void sendHeadersOnly() throws IOException, InterruptedException {
+        if (Log.requests() && request != null) {
+            Log.logRequest(request.toString());
+        }
+        requestContentLen = requestProcessor.contentLength();
+        OutgoingHeaders<Stream<T>> f = headerFrame(requestContentLen);
+        connection.sendFrame(f);
+    }
+
+    void registerStream(int id) {
+        this.streamid = id;
+        connection.putStream(this, streamid);
+    }
+
+    class RequestSubscriber
+        extends RequestProcessors.ProcessorBase
+        implements Flow.Subscriber<ByteBuffer>
+    {
+        // can be < 0 if the actual length is not known.
+        private volatile long remainingContentLength;
+        private volatile Subscription subscription;
+
+        RequestSubscriber(long contentLen) {
+            this.remainingContentLength = contentLen;
+        }
+
+        @Override
+        public void onSubscribe(Flow.Subscription subscription) {
+            if (this.subscription != null) {
+                throw new IllegalStateException();
+            }
+            this.subscription = subscription;
+            subscription.request(1);
+        }
+
+        @Override
+        public void onNext(ByteBuffer item) {
+            if (requestBodyCF.isDone()) {
+                throw new IllegalStateException();
+            }
+
+            try {
+                while (item.hasRemaining()) {
+                    assert !endStreamSent : "internal error, send data after END_STREAM flag";
+                    DataFrame df = getDataFrame(item);
+                    if (remainingContentLength > 0) {
+                        remainingContentLength -= df.getDataLength();
+                        assert remainingContentLength >= 0;
+                        if (remainingContentLength == 0) {
+                            df.setFlag(DataFrame.END_STREAM);
+                            endStreamSent = true;
+                        }
+                    }
+                    connection.sendDataFrame(df);
+                }
+                subscription.request(1);
+            } catch (InterruptedException ex) {
+                subscription.cancel();
+                requestBodyCF.completeExceptionally(ex);
+            }
+        }
+
+        @Override
+        public void onError(Throwable throwable) {
+            if (requestBodyCF.isDone()) {
+                return;
+            }
+            subscription.cancel();
+            requestBodyCF.completeExceptionally(throwable);
+        }
+
+        @Override
+        public void onComplete() {
+            assert endStreamSent || remainingContentLength < 0;
+            try {
+                if (!endStreamSent) {
+                    endStreamSent = true;
+                    connection.sendDataFrame(getEmptyEndStreamDataFrame());
+                }
+                requestBodyCF.complete(null);
+            } catch (InterruptedException ex) {
+                requestBodyCF.completeExceptionally(ex);
+            }
+        }
+    }
+
+    DataFrame getDataFrame(ByteBuffer buffer) throws InterruptedException {
+        int requestAmount = Math.min(connection.getMaxSendFrameSize(), buffer.remaining());
+        // blocks waiting for stream send window, if exhausted
+        int actualAmount = windowController.tryAcquire(requestAmount, streamid);
+        ByteBuffer outBuf = Utils.slice(buffer,  actualAmount);
+        DataFrame df = new DataFrame(streamid, 0 , ByteBufferReference.of(outBuf));
+        return df;
+    }
+
+    private DataFrame getEmptyEndStreamDataFrame() throws InterruptedException {
+        return new DataFrame(streamid, DataFrame.END_STREAM, new ByteBufferReference[0]);
+    }
+
+    /**
+     * A List of responses relating to this stream. Normally there is only
+     * one response, but intermediate responses like 100 are allowed
+     * and must be passed up to higher level before continuing. Deals with races
+     * such as if responses are returned before the CFs get created by
+     * getResponseAsync()
+     */
+
+    final List<CompletableFuture<Response>> response_cfs = new ArrayList<>(5);
+
+    @Override
+    CompletableFuture<Response> getResponseAsync(Executor executor) {
+        CompletableFuture<Response> cf;
+        synchronized (response_cfs) {
+            if (!response_cfs.isEmpty()) {
+                cf = response_cfs.remove(0);
+            } else {
+                cf = new MinimalFuture<>();
+                response_cfs.add(cf);
+            }
+        }
+        Log.logTrace("Response future (stream={0}) is: {1}", streamid, cf);
+        PushGroup<?,?> pg = exchange.getPushGroup();
+        if (pg != null) {
+            // if an error occurs make sure it is recorded in the PushGroup
+            cf = cf.whenComplete((t,e) -> pg.pushError(e));
+        }
+        return cf;
+    }
+
+    /**
+     * Completes the first uncompleted CF on list, and removes it. If there is no
+     * uncompleted CF then creates one (completes it) and adds to list
+     */
+    void completeResponse(Response resp) {
+        synchronized (response_cfs) {
+            CompletableFuture<Response> cf;
+            int cfs_len = response_cfs.size();
+            for (int i=0; i<cfs_len; i++) {
+                cf = response_cfs.get(i);
+                if (!cf.isDone()) {
+                    Log.logTrace("Completing response (streamid={0}): {1}",
+                                 streamid, cf);
+                    cf.complete(resp);
+                    response_cfs.remove(cf);
+                    return;
+                }
+            }
+            cf = MinimalFuture.completedFuture(resp);
+            Log.logTrace("Created completed future (streamid={0}): {1}",
+                         streamid, cf);
+            response_cfs.add(cf);
+        }
+    }
+
+    // methods to update state and remove stream when finished
+
+    synchronized void requestSent() {
+        requestSent = true;
+        if (responseReceived) {
+            close();
+        }
+    }
+
+    final synchronized boolean isResponseReceived() {
+        return responseReceived;
+    }
+
+    synchronized void responseReceived() {
+        responseReceived = true;
+        if (requestSent) {
+            close();
+        }
+    }
+
+    /**
+     * same as above but for errors
+     */
+    void completeResponseExceptionally(Throwable t) {
+        synchronized (response_cfs) {
+            for (CompletableFuture<Response> cf : response_cfs) {
+                if (!cf.isDone()) {
+                    cf.completeExceptionally(t);
+                    response_cfs.remove(cf);
+                    return;
+                }
+            }
+            response_cfs.add(MinimalFuture.failedFuture(t));
+        }
+    }
+
+    private void waitForCompletion() throws IOException {
+        try {
+            requestBodyCF.join();
+        } catch (CompletionException e) {
+            throw Utils.getIOException(e);
+        }
+    }
+
+    void sendBodyImpl() throws IOException, InterruptedException {
+        RequestSubscriber subscriber = new RequestSubscriber(requestContentLen);
+        subscriber.setClient(client);
+        requestProcessor.subscribe(subscriber);
+        waitForCompletion();
+        requestSent();
+    }
+
+    @Override
+    void cancel() {
+        cancel(new IOException("Stream " + streamid + " cancelled"));
+    }
+
+    @Override
+    void cancel(IOException cause) {
+        cancelImpl(cause);
+    }
+
+    // This method sends a RST_STREAM frame
+    void cancelImpl(Throwable e) {
+        if (Log.trace()) {
+            Log.logTrace("cancelling stream {0}: {1}\n", streamid, e);
+        }
+        boolean closing;
+        if (closing = !closed) { // assigning closing to !closed
+            synchronized (this) {
+                if (closing = !closed) { // assigning closing to !closed
+                    closed=true;
+                }
+            }
+        }
+        if (closing) { // true if the stream has not been closed yet
+            inputQ.close();
+        }
+        completeResponseExceptionally(e);
+        try {
+            // will send a RST_STREAM frame
+            connection.resetStream(streamid, ResetFrame.CANCEL);
+        } catch (IOException ex) {
+            Log.logError(ex);
+        }
+    }
+
+    // This method doesn't send any frame
+    void close() {
+        if (closed) return;
+        synchronized(this) {
+            if (closed) return;
+            closed = true;
+        }
+        Log.logTrace("Closing stream {0}", streamid);
+        inputQ.close();
+        connection.closeStream(streamid);
+        Log.logTrace("Stream {0} closed", streamid);
+    }
+
+    static class PushedStream<U,T> extends Stream<T> {
+        final PushGroup<U,T> pushGroup;
+        private final Stream<T> parent;      // used by server push streams
+        // push streams need the response CF allocated up front as it is
+        // given directly to user via the multi handler callback function.
+        final CompletableFuture<Response> pushCF;
+        final CompletableFuture<HttpResponse<T>> responseCF;
+        final HttpRequestImpl pushReq;
+        HttpResponse.BodyHandler<T> pushHandler;
+
+        PushedStream(PushGroup<U,T> pushGroup, HttpClientImpl client,
+                Http2Connection connection, Stream<T> parent,
+                Exchange<T> pushReq) {
+            // ## no request body possible, null window controller
+            super(client, connection, pushReq, null);
+            this.pushGroup = pushGroup;
+            this.pushReq = pushReq.request();
+            this.pushCF = new MinimalFuture<>();
+            this.responseCF = new MinimalFuture<>();
+            this.parent = parent;
+        }
+
+        CompletableFuture<HttpResponse<T>> responseCF() {
+            return responseCF;
+        }
+
+        synchronized void setPushHandler(HttpResponse.BodyHandler<T> pushHandler) {
+            this.pushHandler = pushHandler;
+        }
+
+        synchronized HttpResponse.BodyHandler<T> getPushHandler() {
+            // ignored parameters to function can be used as BodyHandler
+            return this.pushHandler;
+        }
+
+        // Following methods call the super class but in case of
+        // error record it in the PushGroup. The error method is called
+        // with a null value when no error occurred (is a no-op)
+        @Override
+        CompletableFuture<Void> sendBodyAsync(Executor executor) {
+            return super.sendBodyAsync(executor)
+                        .whenComplete((Void v, Throwable t) -> {
+                            pushGroup.pushError(t);
+                        });
+        }
+
+        @Override
+        CompletableFuture<Void> sendHeadersAsync() {
+            return super.sendHeadersAsync()
+                        .whenComplete((Void v, Throwable t) -> {
+                            pushGroup.pushError(t);
+                         });
+        }
+
+        @Override
+        CompletableFuture<Void> sendRequestAsync(Executor executor) {
+            return super.sendRequestAsync(executor)
+                        .whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        CompletableFuture<Response> getResponseAsync(Executor executor) {
+            return pushCF.whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        CompletableFuture<T> readBodyAsync(
+                HttpResponse.BodyHandler<T> handler,
+                boolean returnToCache,
+                Executor executor)
+        {
+            return super.readBodyAsync(handler, returnToCache, executor)
+                        .whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        void completeResponse(Response r) {
+            HttpResponseImpl.logResponse(r);
+            pushCF.complete(r); // not strictly required for push API
+            // start reading the body using the obtained BodyProcessor
+            readBodyAsync(getPushHandler(), false, getExchange().executor())
+                .whenComplete((T body, Throwable t) -> {
+                    if (t != null) {
+                        responseCF.completeExceptionally(t);
+                    } else {
+                        HttpResponseImpl<T> response = new HttpResponseImpl<>(r.request, r, body, getExchange());
+                        responseCF.complete(response);
+                    }
+                });
+        }
+
+        @Override
+        void completeResponseExceptionally(Throwable t) {
+            pushCF.completeExceptionally(t);
+        }
+
+        @Override
+        synchronized void responseReceived() {
+            super.responseReceived();
+        }
+
+        // create and return the PushResponseImpl
+        @Override
+        protected void handleResponse() {
+            HttpConnection c = connection.connection; // TODO: improve
+            responseCode = (int)responseHeaders
+                .firstValueAsLong(":status")
+                .orElse(-1);
+
+            if (responseCode == -1) {
+                completeResponseExceptionally(new IOException("No status code"));
+            }
+
+            this.response = new Response(
+                pushReq, exchange, responseHeaders,
+                responseCode, HttpClient.Version.HTTP_2);
+
+            this.responseContentLen = responseHeaders
+                .firstValueAsLong("content-length")
+                .orElse(-1L);
+
+            if (Log.headers()) {
+                StringBuilder sb = new StringBuilder("RESPONSE HEADERS");
+                sb.append(" (streamid=").append(streamid).append("): ");
+                Log.dumpHeaders(sb, "    ", responseHeaders);
+                Log.logHeaders(sb.toString());
+            }
+
+            // different implementations for normal streams and pushed streams
+            completeResponse(response);
+        }
+    }
+
+    final class StreamWindowUpdateSender extends WindowUpdateSender {
+
+        StreamWindowUpdateSender(Http2Connection connection) {
+            super(connection);
+        }
+
+        @Override
+        int getStreamId() {
+            return streamid;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/TimeoutEvent.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.time.Duration;
+import java.time.Instant;
+
+/**
+ * Timeout event notified by selector thread. Executes the given handler if
+ * the timer not cancelled first.
+ *
+ * Register with {@link HttpClientImpl#registerTimer(TimeoutEvent)}.
+ *
+ * Cancel with {@link HttpClientImpl#cancelTimer(TimeoutEvent)}.
+ */
+abstract class TimeoutEvent implements Comparable<TimeoutEvent> {
+
+    private final Instant deadline;
+
+    TimeoutEvent(Duration duration) {
+        deadline = Instant.now().plus(duration);
+    }
+
+    public abstract void handle();
+
+    public Instant deadline() {
+        return deadline;
+    }
+
+    @Override
+    public int compareTo(TimeoutEvent other) {
+        return this.deadline.compareTo(other.deadline);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WebSocket.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,939 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+
+/**
+ * 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 HttpClient#newWebSocketBuilder(
+ * URI, Listener) builder}. Once a {@code WebSocket} is built, 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, int, String) received}.
+ * The {@code WebSocket} may be also closed {@linkplain #abort() abruptly}.
+ *
+ * <p> Once closed the {@code WebSocket} remains {@linkplain #isClosed() closed}
+ * and cannot be reopened.
+ *
+ * <p> Messages of type {@code X} (where {@code X} is one of: Text, Binary,
+ * Ping, Pong or Close) are sent and received asynchronously through the {@code
+ * WebSocket.send{X}} and {@link WebSocket.Listener}{@code .on{X}} methods
+ * respectively. Each method returns a {@link CompletionStage} which completes
+ * when the operation has completed.
+ *
+ * <p> Note that messages (of any type) are received only if {@linkplain
+ * #request(long) requested}.
+ *
+ * <p> One outstanding send operation is permitted. No further send operation
+ * can be initiated before the previous one has completed. When sending, a
+ * message must not be modified until the returned {@link CompletableFuture}
+ * completes (either normally or exceptionally).
+ *
+ * <p> Text and Binary messages can be sent and received as a whole or in parts.
+ * A whole message is transferred as a sequence of one or more invocations of a
+ * corresponding method where the last invocation is identified via an
+ * additional method argument.
+ *
+ * <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> Unless otherwise stated, {@code null} parameter values will cause methods
+ * and constructors to throw {@link NullPointerException}.
+ *
+ * @implNote This implementation's methods do not block before returning
+ * a {@code CompletableFuture}.
+ *
+ * @since 9
+ */
+public interface WebSocket {
+
+    /**
+     * The WebSocket Close message status code (<code>{@value}</code>),
+     * indicating normal closure, meaning that the purpose for which the
+     * connection was established has been fulfilled.
+     *
+     * @see #sendClose(int, String)
+     * @see Listener#onClose(WebSocket, int, String)
+     */
+    int NORMAL_CLOSURE = 1000;
+
+    /**
+     * The WebSocket Close message status code (<code>{@value}</code>), is
+     * designated for use in applications expecting a status code to indicate
+     * that the connection was closed abnormally, e.g., without sending or
+     * receiving a Close message.
+     *
+     * @see Listener#onClose(WebSocket, int, String)
+     * @see #abort()
+     */
+    int CLOSED_ABNORMALLY = 1006;
+
+    /**
+     * A builder for creating {@code WebSocket} instances.
+     *
+     * <p> To build a {@code WebSocket}, {@linkplain HttpClient#newWebSocketBuilder(
+     * URI, Listener) create} 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).
+     *
+     * <p> Instances of {@code Builder} are not safe for use by multiple threads
+     * without external synchronization.
+     *
+     * @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
+         */
+        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. This subprotocol will be available from {@link
+         * WebSocket#getSubprotocol}. Subprotocols are specified in the order of
+         * preference.
+         *
+         * <p> Each of the given subprotocols must conform to the relevant
+         * rules defined in the WebSocket Protocol.
+         *
+         * <p> If this method is not invoked then no subprotocols are requested.
+         *
+         * @param mostPreferred
+         *         the most preferred subprotocol
+         * @param lesserPreferred
+         *         the lesser preferred subprotocols, with the least preferred
+         *         at the end
+         *
+         * @return this builder
+         */
+        Builder subprotocols(String mostPreferred, String... lesserPreferred);
+
+        /**
+         * Sets a timeout for the opening handshake.
+         *
+         * <p> If the opening handshake does not complete within the specified
+         * duration then the {@code CompletableFuture} returned from {@link
+         * #buildAsync()} completes exceptionally with a {@link
+         * HttpTimeoutException}.
+         *
+         * <p> If this method is not invoked then the timeout is deemed infinite.
+         *
+         * @param timeout
+         *         the timeout, non-{@linkplain Duration#isNegative() negative},
+         *         non-{@linkplain Duration#ZERO ZERO}
+         *
+         * @return this builder
+         */
+        Builder connectTimeout(Duration timeout);
+
+        /**
+         * Builds a {@code WebSocket}.
+         *
+         * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+         * normally 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 WebSocketHandshakeException} -
+         *          if the opening handshake fails
+         * <li> {@link HttpTimeoutException} -
+         *          if the opening handshake does not complete within
+         *          the specified {@linkplain #connectTimeout(Duration) duration}
+         * <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 IllegalArgumentException} -
+         *          if any of the additional {@link #header(String, String)
+         *          headers} are illegal;
+         *          or if any of the WebSocket Protocol rules relevant to {@link
+         *          #subprotocols(String, String...) subprotocols} are violated;
+         *          or if the {@link #connectTimeout(Duration) connect timeout}
+         *          is invalid;
+         * </ul>
+         *
+         * @return a {@code CompletableFuture} with the {@code WebSocket}
+         */
+        CompletableFuture<WebSocket> buildAsync();
+    }
+
+    /**
+     * A listener for events and messages on a {@code WebSocket}.
+     *
+     * <p> Each method of {@code Listener} corresponds to a type of event or a
+     * type of message. The {@code WebSocket} argument of the method is the
+     * {@code WebSocket} the event has occurred (the message has been received)
+     * on. All methods with the same {@code WebSocket} argument 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.
+     *
+     * <ul>
+     * <li> {@link #onOpen(WebSocket) onOpen} <br>
+     * This method is invoked first.
+     * <li> {@link #onText(WebSocket, CharSequence, 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, int, String) onClose}, {@link
+     * #onError(WebSocket, Throwable) onError} <br>
+     * Only one of these methods is invoked, and that method is invoked last.
+     * </ul>
+     *
+     * <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#PART PART} and, finally, with
+     * {@link WebSocket.MessagePart#LAST LAST} markers.
+     *
+     * If any of the methods above throws an exception, {@code onError} is then
+     * invoked with the same {@code WebSocket} and this exception. Exceptions
+     * thrown from {@code onError} or {@code onClose} are ignored.
+     *
+     * <p> When the method returns, the message is deemed received (in
+     * particular, if contained in a {@code ByteBuffer buffer}, the data is
+     * deemed received completely regardless of the result {@code
+     * buffer.hasRemaining()} upon the method's return. After this further
+     * 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 (by convention) means the same as returning an
+     * already completed (normally) {@code CompletionStage}.
+     * If the returned {@code CompletionStage} completes exceptionally, then
+     * {@link #onError(WebSocket, Throwable) onError} will be invoked with the
+     * same {@code WebSocket} and this 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> A {@code WebSocket} implementation never invokes {@code Listener}'s
+     * methods 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 and the first {@code
+         * Listener}'s method to be invoked.
+         *
+         * <p> This 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 same
+         * {@code WebSocket} and this exception.
+         *
+         * @implSpec The default implementation of this method behaves as if:
+         *
+         * <pre>{@code
+         *     webSocket.request(1);
+         * }</pre>
+         *
+         * @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 same
+         * {@code WebSocket} and this exception.
+         *
+         * @implSpec The default implementation of this method behaves as if:
+         *
+         * <pre>{@code
+         *     webSocket.request(1);
+         *     return null;
+         * }</pre>
+         *
+         * @implNote This implementation passes only complete UTF-16 sequences
+         * to the {@code onText} method.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         * @param part
+         *         the part
+         *
+         * @return a {@code CompletionStage} which completes when the message
+         * processing is done; or {@code null} if already done
+         */
+        default CompletionStage<?> onText(WebSocket webSocket,
+                                          CharSequence 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 the same
+         * {@code WebSocket} and this exception.
+         *
+         * @implSpec The default implementation of this method behaves as if:
+         *
+         * <pre>{@code
+         *     webSocket.request(1);
+         *     return null;
+         * }</pre>
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         * @param part
+         *         the part
+         *
+         * @return a {@code CompletionStage} which 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 {@code WebSocket} handles Ping messages by replying with
+         * appropriate Pong messages using a strategy of its choice, but within
+         * the boundaries of the WebSocket Protocol. The {@code WebSocket} may
+         * invoke {@code onPing} after handling a Ping message, before doing so
+         * or in parallel with it. In other words no particular ordering is
+         * guaranteed. If an error occurs while implementation handles this Ping
+         * message, then {@code onError} will be invoked with this error. For
+         * more details on handling Ping messages see RFC 6455 sections
+         * <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">5.5.2. Ping</a>
+         * and
+         * <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">5.5.3. Pong</a>.
+         *
+         * <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.
+         *
+         * @implSpec The default implementation of this method behaves as if:
+         *
+         * <pre>{@code
+         *     webSocket.request(1);
+         *     return null;
+         * }</pre>
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         *
+         * @return a {@code CompletionStage} which completes when the message
+         * processing is done; or {@code null} if already done
+         */
+        default CompletionStage<?> onPing(WebSocket webSocket,
+                                          ByteBuffer message) {
+            webSocket.request(1);
+            return null;
+        }
+
+        /**
+         * 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 of this method behaves as if:
+         *
+         * <pre>{@code
+         *     webSocket.request(1);
+         *     return null;
+         * }</pre>
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         *
+         * @return a {@code CompletionStage} which 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> A Close message consists of a status code and a reason for
+         * closing. The status code is an integer in the range {@code 1000 <=
+         * code <= 65535}. The {@code reason} is a short string that has an
+         * UTF-8 representation not longer than {@code 123} bytes. For more
+         * details on Close message, status codes and reason see RFC 6455 sections
+         * <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">5.5.1. Close</a>
+         * and
+         * <a href="https://tools.ietf.org/html/rfc6455#section-7.4">7.4. Status Codes</a>.
+         *
+         * <p> After the returned {@code CompletionStage} has completed
+         * (normally or exceptionally), the {@code WebSocket} completes the
+         * closing handshake by replying with an appropriate Close message.
+         *
+         * <p> This implementation replies with a Close message that has the
+         * same code this message has and an empty reason.
+         *
+         * <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.
+         *
+         * <p> The {@code WebSocket} will close at the earliest of completion of
+         * the returned {@code CompletionStage} or sending a Close message. In
+         * particular, if a Close message has been {@link WebSocket#sendClose()
+         * sent} before, then this invocation completes the closing handshake
+         * and by the time this method is invoked, the {@code WebSocket} will
+         * have been closed.
+         *
+         * @implSpec The default implementation of this method behaves as if:
+         *
+         * <pre>{@code
+         *     return null;
+         * }</pre>
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param statusCode
+         *         the status code
+         * @param reason
+         *         the reason
+         *
+         * @return a {@code CompletionStage} which completes when the {@code
+         * WebSocket} can be closed; or {@code null} if it can be closed immediately
+         *
+         * @see #NORMAL_CLOSURE
+         */
+        default CompletionStage<?> onClose(WebSocket webSocket,
+                                           int statusCode,
+                                           String reason) {
+            return null;
+        }
+
+        /**
+         * Notifies an I/O or protocol error has occurred.
+         *
+         * <p> The {@code onError} method does not correspond to any message
+         * from the WebSocket Protocol. It is a synthetic event and the last
+         * {@code Listener}'s method to be invoked. It is invoked at most once
+         * but after {@code onOpen}. If an exception is thrown from this method,
+         * it is ignored.
+         *
+         * <p> Note that the WebSocket Protocol requires <i>some</i> errors
+         * occur in the incoming destination must be fatal to the connection. In
+         * such cases the implementation takes care of <i>Failing the WebSocket
+         * Connection</i>: by the time {@code onError} is invoked, the {@code
+         * WebSocket} will have been closed. Any outstanding or subsequent send
+         * operation will complete exceptionally with an {@code IOException}.
+         * For more details on Failing the WebSocket Connection see RFC 6455
+         * section <a href="https://tools.ietf.org/html/rfc6455#section-7.1.7">7.1.7. Fail the WebSocket Connection</a>.
+         *
+         * @apiNote Errors associated with sending messages are reported to the
+         * {@code CompletableFuture}s {@code sendX} methods return, rather than
+         * to this this method.
+         *
+         * @implSpec The default implementation of this method does nothing.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param error
+         *         the error
+         */
+        default void onError(WebSocket webSocket, Throwable error) { }
+    }
+
+    /**
+     * A marker used by {@link WebSocket.Listener} in cases where a partial
+     * message may be received.
+     *
+     * @see Listener#onText(WebSocket, CharSequence, MessagePart)
+     * @see Listener#onBinary(WebSocket, ByteBuffer, MessagePart)
+     *
+     * @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 consisting of a single part.
+         */
+        WHOLE
+    }
+
+    /**
+     * Sends a Text message with characters from the given {@code CharSequence}.
+     *
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
+     *
+     * <p> The {@code CharSequence} must 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 IllegalArgumentException} -
+     *          if {@code message} is a malformed UTF-16 sequence
+     * <li> {@link IllegalStateException} -
+     *          if the {@code WebSocket} is closed;
+     *          or if a Close message has been sent;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Binary message was sent with {@code isLast == false}
+     * <li> {@link IOException} -
+     *          if an I/O error occurs during this operation;
+     *          or if the {@code WebSocket} has been closed due to an error;
+     * </ul>
+     *
+     * @implNote This implementation does not accept partial UTF-16 sequences.
+     * In case such a sequence is passed, a returned {@code CompletableFuture}
+     * completes exceptionally with {@code IOException}.
+     *
+     * @param message
+     *         the message
+     * @param isLast
+     *         {@code true} if this is the last part of the message,
+     *         {@code false} otherwise
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     */
+    CompletableFuture<WebSocket> 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 a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
+     *
+     * <p> The {@code CharSequence} must 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 IllegalArgumentException} -
+     *          if {@code message} is a malformed UTF-16 sequence
+     * <li> {@link IllegalStateException} -
+     *          if the {@code WebSocket} is closed;
+     *          or if a Close message has been sent;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Binary message was sent with {@code isLast == false}
+     * <li> {@link IOException} -
+     *          if an I/O error occurs during this operation;
+     *          or if the {@code WebSocket} has been closed due to an error;
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     */
+    default CompletableFuture<WebSocket> sendText(CharSequence message) {
+        return sendText(message, true);
+    }
+
+    /**
+     * Sends a Binary message with bytes from the given {@code ByteBuffer}.
+     *
+     * <p> Returns a {@code CompletableFuture<WebSocket>} 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 IllegalStateException} -
+     *          if the {@code WebSocket} is closed;
+     *          or if a Close message has been sent;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Text message was sent with {@code isLast == false}
+     * <li> {@link IOException} -
+     *          if an I/O error occurs during this operation;
+     *          or if the {@code WebSocket} has been closed due to an error
+     * </ul>
+     *
+     * @param message
+     *         the message
+     * @param isLast
+     *         {@code true} if this is the last part of the message,
+     *         {@code false} otherwise
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     */
+    CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast);
+
+    /**
+     * Sends a Ping message with bytes from the given ByteBuffer.
+     *
+     * <p> Returns a {@code CompletableFuture<WebSocket>} 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 IllegalArgumentException} -
+     *          if {@code message.remaining() > 125}
+     * <li> {@link IllegalStateException} -
+     *          if the {@code WebSocket} is closed;
+     *          or if a Close message has been sent;
+     *          or if there is an outstanding send operation
+     * <li> {@link IOException} -
+     *          if an I/O error occurs during this operation;
+     *          or if the {@code WebSocket} has been closed due to an error
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     */
+    CompletableFuture<WebSocket> sendPing(ByteBuffer message);
+
+    /**
+     * Sends a Pong message with bytes from the given ByteBuffer.
+     *
+     * <p> Returns a {@code CompletableFuture<WebSocket>} 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 must be
+     * 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 IllegalArgumentException} -
+     *          if {@code message.remaining() > 125}
+     * <li> {@link IllegalStateException} -
+     *          if the {@code WebSocket} is closed;
+     *          or if a Close message has been sent;
+     *          or if there is an outstanding send operation
+     * <li> {@link IOException} -
+     *          if an I/O error occurs during this operation;
+     *          or if the {@code WebSocket} has been closed due to an error
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     */
+    CompletableFuture<WebSocket> sendPong(ByteBuffer message);
+
+    /**
+     * Sends a Close message with the given status code and the reason.
+     *
+     * <p> When this method has been invoked, no further messages can be sent.
+     *
+     * <p> The {@code statusCode} is an integer in the range {@code 1000 <= code
+     * <= 4999}. However, not all status codes may be legal in some
+     * implementations. Regardless of an implementation,
+     * <code>{@value jdk.incubator.http.WebSocket#NORMAL_CLOSURE}</code>
+     * is always legal and {@code 1002}, {@code 1003}, {@code 1005}, {@code
+     * 1006}, {@code 1007}, {@code 1009}, {@code 1010}, {@code 1012}, {@code
+     * 1013} and {@code 1015} are always illegal codes.
+     *
+     * <p> The {@code reason} is a short string that must have an UTF-8
+     * representation not longer than {@code 123} bytes. For more details on
+     * Close message, status codes and reason see RFC 6455 sections
+     * <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">5.5.1. Close</a>
+     * and
+     * <a href="https://tools.ietf.org/html/rfc6455#section-7.4">7.4. Status Codes</a>.
+     *
+     * <p> The method returns a {@code CompletableFuture<WebSocket>} 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 IllegalArgumentException} -
+     *          if the {@code statusCode} has an illegal value;
+     *          or if {@code reason} doesn't have an UTF-8 representation of
+     *          length {@code <= 123}
+     * <li> {@link IOException} -
+     *          if an I/O error occurs during this operation;
+     *          or the {@code WebSocket} has been closed due to an error
+     * </ul>
+     *
+     * <p> If this method has already been invoked or the {@code WebSocket} is
+     * closed, then subsequent invocations of this method have no effect and the
+     * returned {@code CompletableFuture} completes normally.
+     *
+     * <p> If a Close message has been {@linkplain Listener#onClose(WebSocket,
+     * int, String) received} before, then this invocation completes the closing
+     * handshake and by the time the returned {@code CompletableFuture}
+     * completes, the {@code WebSocket} will have been closed.
+     *
+     * @param statusCode
+     *         the status code
+     * @param reason
+     *         the reason
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     *
+     * @see #sendClose()
+     */
+    CompletableFuture<WebSocket> sendClose(int statusCode, String reason);
+
+    /**
+     * Sends an empty Close message.
+     *
+     * <p> When this method has been invoked, no further messages can be sent.
+     *
+     * <p> For more details on Close message see RFC 6455 section
+     * <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">5.5.1. Close</a>
+     *
+     * <p> The method returns a {@code CompletableFuture<WebSocket>} 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} has been closed due to an error
+     * </ul>
+     *
+     * <p> If this method has already been invoked or the {@code WebSocket} is
+     * closed, then subsequent invocations of this method have no effect and the
+     * returned {@code CompletableFuture} completes normally.
+     *
+     * <p> If a Close message has been {@linkplain Listener#onClose(WebSocket,
+     * int, String) received} before, then this invocation completes the closing
+     * handshake and by the time the returned {@code CompletableFuture}
+     * completes, the {@code WebSocket} will have been closed.
+     *
+     * @return a {@code CompletableFuture} with this {@code WebSocket}
+     *
+     * @see #sendClose(int, String)
+     */
+    CompletableFuture<WebSocket> sendClose();
+
+    /**
+     * Allows {@code n} more messages to be received by the {@link Listener
+     * Listener}.
+     *
+     * <p> The actual number of received messages might be fewer if a Close
+     * message is received, the {@code WebSocket} closes or an error occurs.
+     *
+     * <p> A {@code WebSocket} that has just been built, hasn't requested
+     * anything yet. Usually the initial request for messages is made in {@link
+     * Listener#onOpen(jdk.incubator.http.WebSocket) Listener.onOpen}.
+     *
+     * <p> If the {@code WebSocket} is closed then invoking this method has no
+     * effect.
+     *
+     * @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, this 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}
+     */
+    void request(long n);
+
+    /**
+     * Returns a {@linkplain Builder#subprotocols(String, String...) subprotocol}
+     * which has been chosen for this {@code WebSocket}.
+     *
+     * @return a subprotocol, or an empty {@code String} if there is none
+     */
+    String getSubprotocol();
+
+    /**
+     * Tells whether the {@code WebSocket} is closed.
+     *
+     * <p> When a {@code WebSocket} is closed no further messages can be sent or
+     * received.
+     *
+     * @return {@code true} if the {@code WebSocket} is closed,
+     *         {@code false} otherwise
+     */
+    boolean isClosed();
+
+    /**
+     * Closes the {@code WebSocket} abruptly.
+     *
+     * <p> This method may be invoked at any time. This method closes the
+     * underlying TCP connection and puts the {@code WebSocket} into a closed
+     * state.
+     *
+     * <p> As the result {@link Listener#onClose(WebSocket, int, String)
+     * Listener.onClose} will be invoked with the status code {@link
+     * #CLOSED_ABNORMALLY} unless either {@code onClose} or {@link
+     * Listener#onError(WebSocket, Throwable) onError} has been invoked before.
+     * In which case no additional invocation will happen.
+     *
+     * <p> 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WebSocketHandshakeException.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.io.IOException;
+
+/**
+ * An exception used to signal the opening handshake failed.
+ *
+ * @since 9
+ */
+public final class WebSocketHandshakeException extends IOException {
+
+    private static final long serialVersionUID = 1L;
+
+    private final transient HttpResponse<?> response;
+
+    public WebSocketHandshakeException(HttpResponse<?> response) {
+        this.response = response;
+    }
+
+    /**
+     * Returns the server's counterpart of the opening handshake.
+     *
+     * <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;
+    }
+
+    @Override
+    public WebSocketHandshakeException initCause(Throwable cause) {
+        return (WebSocketHandshakeException) super.initCause(cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WindowController.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * A Simple blocking Send Window Flow-Controller that is used to control
+ * outgoing Connection and Stream flows, per HTTP/2 connection.
+ *
+ * A Http2Connection has its own unique single instance of a WindowController
+ * that it shares with its Streams. Each stream must acquire the appropriate
+ * amount of Send Window from the controller before sending data.
+ *
+ * WINDOW_UPDATE frames, both connection and stream specific, must notify the
+ * controller of their increments. SETTINGS frame's INITIAL_WINDOW_SIZE must
+ * notify the controller so that it can adjust the active stream's window size.
+ */
+final class WindowController {
+
+    /**
+     * Default initial connection Flow-Control Send Window size, as per HTTP/2.
+     */
+    private static final int DEFAULT_INITIAL_WINDOW_SIZE = 64 * 1024 - 1;
+
+    /** The connection Send Window size. */
+    private int connectionWindowSize;
+    /** A Map of the active streams, where the key is the stream id, and the
+     *  value is the stream's Send Window size, which may be negative. */
+    private final Map<Integer,Integer> streams = new HashMap<>();
+
+    private final ReentrantLock controllerLock = new ReentrantLock();
+
+    private final Condition notExhausted = controllerLock.newCondition();
+
+    /** A Controller with the default initial window size. */
+    WindowController() {
+        connectionWindowSize = DEFAULT_INITIAL_WINDOW_SIZE;
+    }
+
+    /** A Controller with the given initial window size. */
+    WindowController(int initialConnectionWindowSize) {
+        connectionWindowSize = initialConnectionWindowSize;
+    }
+
+    /** Registers the given stream with this controller. */
+    void registerStream(int streamid, int initialStreamWindowSize) {
+        controllerLock.lock();
+        try {
+            Integer old = streams.put(streamid, initialStreamWindowSize);
+            if (old != null)
+                throw new InternalError("Unexpected entry [" + old + "] for streamid: " + streamid);
+        } finally {
+            controllerLock.unlock();
+        }
+    }
+
+    /** Removes/De-registers the given stream with this controller. */
+    void removeStream(int streamid) {
+        controllerLock.lock();
+        try {
+            Integer old = streams.remove(streamid);
+            // Odd stream numbers (client streams) should have been registered.
+            // Even stream numbers (server streams - aka Push Streams) should
+            // not be registered
+            final boolean isClientStream = (streamid % 2) == 1;
+            if (old == null && isClientStream) {
+                throw new InternalError("Expected entry for streamid: " + streamid);
+            } else if (old != null && !isClientStream) {
+                throw new InternalError("Unexpected entry for streamid: " + streamid);
+            }
+        } finally {
+            controllerLock.unlock();
+        }
+    }
+
+    /**
+     * Attempts to acquire the requested amount of Send Window for the given
+     * stream.
+     *
+     * The actual amount of Send Window available may differ from the requested
+     * amount. The actual amount, returned by this method, is the minimum of,
+     * 1) the requested amount, 2) the stream's Send Window, and 3) the
+     * connection's Send Window.
+     *
+     * This method ( currently ) blocks until some positive amount of Send
+     * Window is available.
+     */
+    int tryAcquire(int requestAmount, int streamid) throws InterruptedException {
+        controllerLock.lock();
+        try {
+            int x = 0;
+            Integer streamSize = 0;
+            while (x <= 0) {
+                streamSize = streams.get(streamid);
+                if (streamSize == null)
+                    throw new InternalError("Expected entry for streamid: " + streamid);
+                x = Math.min(requestAmount,
+                             Math.min(streamSize, connectionWindowSize));
+
+                if (x <= 0)  // stream window size may be negative
+                    notExhausted.await();
+            }
+
+            streamSize -= x;
+            streams.put(streamid, streamSize);
+            connectionWindowSize -= x;
+            return x;
+        } finally {
+            controllerLock.unlock();
+        }
+    }
+
+    /**
+     * Increases the Send Window size for the connection.
+     *
+     * @return false if, and only if, the addition of the given amount would
+     *         cause the Send Window to exceed 2^31-1 (overflow), otherwise true
+     */
+    boolean increaseConnectionWindow(int amount) {
+        controllerLock.lock();
+        try {
+            int size = connectionWindowSize;
+            size += amount;
+            if (size < 0)
+                return false;
+            connectionWindowSize = size;
+            notExhausted.signalAll();
+        } finally {
+            controllerLock.unlock();
+        }
+        return true;
+    }
+
+    /**
+     * Increases the Send Window size for the given stream.
+     *
+     * @return false if, and only if, the addition of the given amount would
+     *         cause the Send Window to exceed 2^31-1 (overflow), otherwise true
+     */
+    boolean increaseStreamWindow(int amount, int streamid) {
+        controllerLock.lock();
+        try {
+            Integer size = streams.get(streamid);
+            if (size == null)
+                throw new InternalError("Expected entry for streamid: " + streamid);
+            size += amount;
+            if (size < 0)
+                return false;
+            streams.put(streamid, size);
+            notExhausted.signalAll();
+        } finally {
+            controllerLock.unlock();
+        }
+        return true;
+    }
+
+    /**
+     * Adjusts, either increases or decreases, the active streams registered
+     * with this controller.  May result in a stream's Send Window size becoming
+     * negative.
+     */
+    void adjustActiveStreams(int adjustAmount) {
+        assert adjustAmount != 0;
+
+        controllerLock.lock();
+        try {
+            for (Map.Entry<Integer,Integer> entry : streams.entrySet()) {
+                int streamid = entry.getKey();
+                // the API only supports sending on Streams initialed by
+                // the client, i.e. odd stream numbers
+                if (streamid != 0 && (streamid % 2) != 0) {
+                    Integer size = entry.getValue();
+                    size += adjustAmount;
+                    streams.put(streamid, size);
+                }
+            }
+        } finally {
+            controllerLock.unlock();
+        }
+    }
+
+    /** Returns the Send Window size for the connection. */
+    int connectionWindowSize() {
+        controllerLock.lock();
+        try {
+            return connectionWindowSize;
+        } finally {
+            controllerLock.unlock();
+        }
+    }
+
+    /** Returns the Send Window size for the given stream. */
+    int streamWindowSize(int streamid) {
+        controllerLock.lock();
+        try {
+            Integer size = streams.get(streamid);
+            if (size == null)
+                throw new InternalError("Expected entry for streamid: " + streamid);
+            return size;
+        } finally {
+            controllerLock.unlock();;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WindowUpdateSender.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ */
+package jdk.incubator.http;
+
+import jdk.incubator.http.internal.frame.SettingsFrame;
+import jdk.incubator.http.internal.frame.WindowUpdateFrame;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+abstract class WindowUpdateSender {
+
+
+    final int limit;
+    final Http2Connection connection;
+    final AtomicInteger received = new AtomicInteger(0);
+
+    WindowUpdateSender(Http2Connection connection) {
+        this(connection, connection.clientSettings.getParameter(SettingsFrame.INITIAL_WINDOW_SIZE));
+    }
+
+    WindowUpdateSender(Http2Connection connection, int initWindowSize) {
+        this(connection, connection.getMaxReceiveFrameSize(), initWindowSize);
+    }
+
+    WindowUpdateSender(Http2Connection connection, int maxFrameSize, int initWindowSize) {
+        this.connection = connection;
+        int v0 = Math.max(0, initWindowSize - maxFrameSize);
+        int v1 = (initWindowSize + (maxFrameSize - 1)) / maxFrameSize;
+        v1 = v1 * maxFrameSize / 2;
+        // send WindowUpdate heuristic:
+        // - we got data near half of window size
+        //   or
+        // - remaining window size reached max frame size.
+        limit = Math.min(v0, v1);
+    }
+
+    abstract int getStreamId();
+
+    void update(int delta) {
+        if (received.addAndGet(delta) > limit) {
+            synchronized (this) {
+                int tosend = received.get();
+                if( tosend > limit) {
+                    received.getAndAdd(-tosend);
+                    sendWindowUpdate(tosend);
+                }
+            }
+        }
+    }
+
+    void sendWindowUpdate(int delta) {
+        connection.sendUnorderedFrame(new WindowUpdateFrame(getStreamId(), delta));
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/AsyncWriteQueue.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http.internal.common;
+
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BiConsumer;
+
+public class AsyncWriteQueue implements Closeable {
+
+    private static final int IDLE    = 0;     // nobody is flushing from the queue
+    private static final int FLUSHING = 1;    // there is the only thread flushing from the queue
+    private static final int REFLUSHING = 2;  // while one thread was flushing from the queue
+                                              // the other thread put data into the queue.
+                                              // flushing thread should recheck queue before switching to idle state.
+    private static final int DELAYED = 3;     // flushing is delayed
+                                              // either by PlainHttpConnection.WriteEvent registration, or
+                                              // SSL handshaking
+
+    private static final int CLOSED = 4;      // queue is closed
+
+    private final AtomicInteger state = new AtomicInteger(IDLE);
+    private final Deque<ByteBufferReference[]> queue = new ConcurrentLinkedDeque<>();
+    private final BiConsumer<ByteBufferReference[], AsyncWriteQueue> consumeAction;
+
+    // Queue may be processed in two modes:
+    // 1. if(!doFullDrain) - invoke callback on each chunk
+    // 2. if(doFullDrain)  - drain the whole queue, merge all chunks into the single array and invoke callback
+    private final boolean doFullDrain;
+
+    private ByteBufferReference[] delayedElement = null;
+
+    public AsyncWriteQueue(BiConsumer<ByteBufferReference[], AsyncWriteQueue> consumeAction) {
+        this(consumeAction, true);
+    }
+
+    public AsyncWriteQueue(BiConsumer<ByteBufferReference[], AsyncWriteQueue> consumeAction, boolean doFullDrain) {
+        this.consumeAction = consumeAction;
+        this.doFullDrain = doFullDrain;
+    }
+
+    public void put(ByteBufferReference[] e) throws IOException {
+        ensureOpen();
+        queue.addLast(e);
+    }
+
+    public void putFirst(ByteBufferReference[] e) throws IOException {
+        ensureOpen();
+        queue.addFirst(e);
+    }
+
+    /**
+     * retruns true if flushing was performed
+     * @return
+     * @throws IOException
+     */
+    public boolean flush() throws IOException {
+        while(true) {
+            switch (state.get()) {
+                case IDLE:
+                    if(state.compareAndSet(IDLE, FLUSHING)) {
+                        flushLoop();
+                        return true;
+                    }
+                    break;
+                case FLUSHING:
+                    if(state.compareAndSet(FLUSHING, REFLUSHING)) {
+                        return false;
+                    }
+                    break;
+                case REFLUSHING:
+                case DELAYED:
+                    return false;
+                case CLOSED:
+                    throw new IOException("Queue closed");
+            }
+        }
+    }
+
+    /*
+     *  race invocations of flushDelayed are not allowed.
+     *  flushDelayed should be invoked only from:
+     *   - SelectorManager thread
+     *   - Handshaking thread
+     */
+    public void flushDelayed() throws IOException {
+        ensureOpen();
+        if(!state.compareAndSet(DELAYED, FLUSHING)) {
+            ensureOpen(); // if CAS failed when close was set - throw proper exception
+            throw new RuntimeException("Shouldn't happen");
+        }
+        flushLoop();
+    }
+
+    private ByteBufferReference[] drain(ByteBufferReference[] prev) {
+        assert prev != null;
+        if(doFullDrain) {
+            ByteBufferReference[] next = queue.poll();
+            if(next == null) {
+                return prev;
+            }
+            List<ByteBufferReference> drained = new ArrayList<>();
+            drained.addAll(Arrays.asList(prev));
+            drained.addAll(Arrays.asList(next));
+            while ((next = queue.poll()) != null) {
+                drained.addAll(Arrays.asList(next));
+            }
+            return drained.toArray(new ByteBufferReference[0]);
+        } else {
+            return prev;
+        }
+    }
+
+    private ByteBufferReference[] drain() {
+        ByteBufferReference[] next = queue.poll();
+        return next == null ? null : drain(next);
+    }
+
+    private void flushLoop() throws IOException {
+        ByteBufferReference[] element;
+        if (delayedElement != null) {
+            element = drain(delayedElement);
+            delayedElement = null;
+        } else {
+            element = drain();
+        }
+        while(true) {
+            while (element != null) {
+                consumeAction.accept(element, this);
+                if (state.get() == DELAYED) {
+                    return;
+                }
+                element = drain();
+            }
+            switch (state.get()) {
+                case IDLE:
+                case DELAYED:
+                    throw new RuntimeException("Shouldn't happen");
+                case FLUSHING:
+                    if(state.compareAndSet(FLUSHING, IDLE)) {
+                        return;
+                    }
+                    break;
+                case REFLUSHING:
+                    // We need to check if new elements were put after last poll() and do graceful exit
+                    state.compareAndSet(REFLUSHING, FLUSHING);
+                    break;
+                case CLOSED:
+                    throw new IOException("Queue closed");
+            }
+            element = drain();
+        }
+    }
+
+    /*
+     * The methods returns unprocessed chunk of buffers into beginning of the queue.
+     * Invocation of the method allowed only inside consume callback,
+     * and consume callback is invoked only when the queue in FLUSHING or REFLUSHING state.
+     */
+    public void setDelayed(ByteBufferReference[] delayedElement) throws IOException {
+        while(true) {
+            int state = this.state.get();
+            switch (state) {
+                case IDLE:
+                case DELAYED:
+                    throw new RuntimeException("Shouldn't happen");
+                case FLUSHING:
+                case REFLUSHING:
+                    if(this.state.compareAndSet(state, DELAYED)) {
+                        this.delayedElement = delayedElement;
+                        return;
+                    }
+                    break;
+                case CLOSED:
+                    throw new IOException("Queue closed");
+            }
+        }
+
+    }
+
+    private void ensureOpen() throws IOException {
+        if (state.get() == CLOSED) {
+            throw new IOException("Queue closed");
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        state.getAndSet(CLOSED);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/BufferHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.common;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Implemented by buffer pools.
+ */
+public interface BufferHandler {
+
+    ByteBuffer getBuffer();
+
+    void returnBuffer(ByteBuffer buffer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/ByteBufferPool.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.common;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * The class provides reuse of ByteBuffers.
+ * It is supposed that all requested buffers have the same size for a long period of time.
+ * That is why there is no any logic splitting buffers into different buckets (by size). It's unnecessary.
+ *
+ * At the same moment it is allowed to change requested buffers size (all smaller buffers will be discarded).
+ * It may be needed for example, if after rehandshaking netPacketBufferSize was changed.
+ */
+public class ByteBufferPool {
+
+    private final java.util.Queue<ByteBuffer> pool = new ConcurrentLinkedQueue<>();
+
+    public ByteBufferPool() {
+    }
+
+    public ByteBufferReference get(int size) {
+        ByteBuffer buffer;
+        while ((buffer = pool.poll()) != null) {
+            if (buffer.capacity() >= size) {
+                return ByteBufferReference.of(buffer, this);
+            }
+        }
+        return ByteBufferReference.of(ByteBuffer.allocate(size), this);
+    }
+
+    public void release(ByteBuffer buffer) {
+        buffer.clear();
+        pool.offer(buffer);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/ByteBufferReference.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.common;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+public class ByteBufferReference  implements Supplier<ByteBuffer> {
+
+    private ByteBuffer buffer;
+    private final ByteBufferPool pool;
+
+    public static ByteBufferReference of(ByteBuffer buffer) {
+        return of(buffer, null);
+    }
+
+    public static ByteBufferReference of(ByteBuffer buffer, ByteBufferPool pool) {
+        Objects.requireNonNull(buffer);
+        return new ByteBufferReference(buffer, pool);
+    }
+
+    public static ByteBuffer[] toBuffers(ByteBufferReference... refs) {
+        ByteBuffer[] bufs = new ByteBuffer[refs.length];
+        for (int i = 0; i < refs.length; i++) {
+            bufs[i] = refs[i].get();
+        }
+        return bufs;
+    }
+
+    public static ByteBufferReference[] toReferences(ByteBuffer... buffers) {
+        ByteBufferReference[] refs = new ByteBufferReference[buffers.length];
+        for (int i = 0; i < buffers.length; i++) {
+            refs[i] = of(buffers[i]);
+        }
+        return refs;
+    }
+
+
+    public static void clear(ByteBufferReference[] refs) {
+        for(ByteBufferReference ref : refs) {
+            ref.clear();
+        }
+    }
+
+    private ByteBufferReference(ByteBuffer buffer, ByteBufferPool pool) {
+        this.buffer = buffer;
+        this.pool = pool;
+    }
+
+    @Override
+    public ByteBuffer get() {
+        ByteBuffer buf = this.buffer;
+        assert buf!=null : "getting ByteBuffer after clearance";
+        return buf;
+    }
+
+    public void clear() {
+        ByteBuffer buf = this.buffer;
+        assert buf!=null : "double ByteBuffer clearance";
+        this.buffer = null;
+        if (pool != null) {
+            pool.release(buf);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/ExceptionallyCloseable.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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.
+ */
+
+package jdk.incubator.http.internal.common;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Implemented by closeable objects which might be able to report
+ * an error when closed due to exceptional conditions.
+ */
+public interface ExceptionallyCloseable extends Closeable {
+
+    /**
+     * Called when an instance of {@code ExceptionallyCloseable} is closed
+     * due to some exceptional condition revealed by {@code cause}.
+     *
+     * @implSpec The default implementation of this method simply calls
+     *           {@link #close()}. Implementation of this interface are
+     *           suppose to override this method in order to ensure that
+     *           the cause is properly reported.
+     *
+     * @param cause The reason for which the object is closed.
+     * @throws IOException if {@link #close()} fails.
+     */
+    public default void closeExceptionally(Throwable cause) throws IOException {
+        close();
+    }
+
+    public static void close(Throwable t, Closeable c) throws IOException {
+        if (c instanceof ExceptionallyCloseable) {
+            ((ExceptionallyCloseable)c).closeExceptionally(t);
+        } else {
+            c.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/HttpHeadersImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.common;
+
+import jdk.incubator.http.HttpHeaders;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.OptionalLong;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Implementation of HttpHeaders.
+ */
+public class HttpHeadersImpl implements HttpHeaders {
+
+    private final TreeMap<String,List<String>> headers;
+
+    public HttpHeadersImpl() {
+        headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    }
+
+    @Override
+    public Optional<String> firstValue(String name) {
+        List<String> l = headers.get(name);
+        return Optional.ofNullable(l == null ? null : l.get(0));
+    }
+
+    @Override
+    public List<String> allValues(String name) {
+        return headers.get(name);
+    }
+
+    @Override
+    public Map<String, List<String>> map() {
+        return Collections.unmodifiableMap(headers);
+    }
+
+    public Map<String, List<String>> directMap() {
+        return headers;
+    }
+
+    // package private mutators
+
+    public HttpHeadersImpl deepCopy() {
+        HttpHeadersImpl h1 = new HttpHeadersImpl();
+        TreeMap<String,List<String>> headers1 = h1.headers;
+        Set<String> keys = headers.keySet();
+        for (String key : keys) {
+            List<String> vals = headers.get(key);
+            List<String> vals1 = new ArrayList<>(vals);
+            headers1.put(key, vals1);
+        }
+        return h1;
+    }
+
+    public void addHeader(String name, String value) {
+        headers.computeIfAbsent(name, k -> new ArrayList<>(1))
+               .add(value);
+    }
+
+    public void setHeader(String name, String value) {
+        List<String> values = new ArrayList<>(1); // most headers has one value
+        values.add(value);
+        headers.put(name, values);
+    }
+
+    @Override
+    public OptionalLong firstValueAsLong(String name) {
+        List<String> l = headers.get(name);
+        if (l == null) {
+            return OptionalLong.empty();
+        } else {
+            String v = l.get(0);
+            return OptionalLong.of(Long.parseLong(v));
+        }
+    }
+
+    public void clear() {
+        headers.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Log.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.common;
+
+import java.io.IOException;
+import jdk.incubator.http.HttpHeaders;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Supplier;
+import jdk.incubator.http.internal.frame.DataFrame;
+import jdk.incubator.http.internal.frame.Http2Frame;
+import jdk.incubator.http.internal.frame.WindowUpdateFrame;
+
+/**
+ * -Djava.net.HttpClient.log=
+ *          errors,requests,headers,
+ *          frames[:control:data:window:all..],content,ssl,trace
+ *
+ * Any of errors, requests, headers or content are optional.
+ *
+ * Other handlers may be added. All logging is at level INFO
+ *
+ * Logger name is "jdk.httpclient.HttpClient"
+ */
+// implements System.Logger in order to be skipped when printing the caller's
+// information
+public abstract class Log implements System.Logger {
+
+    static final String logProp = "jdk.httpclient.HttpClient.log";
+
+    public static final int OFF = 0;
+    public static final int ERRORS = 0x1;
+    public static final int REQUESTS = 0x2;
+    public static final int HEADERS = 0x4;
+    public static final int CONTENT = 0x8;
+    public static final int FRAMES = 0x10;
+    public static final int SSL = 0x20;
+    public static final int TRACE = 0x40;
+    static int logging;
+
+    // Frame types: "control", "data", "window", "all"
+    public static final int CONTROL = 1; // all except DATA and WINDOW_UPDATES
+    public static final int DATA = 2;
+    public static final int WINDOW_UPDATES = 4;
+    public static final int ALL = CONTROL| DATA | WINDOW_UPDATES;
+    static int frametypes;
+
+    static final System.Logger logger;
+
+    static {
+        String s = Utils.getNetProperty(logProp);
+        if (s == null) {
+            logging = OFF;
+        } else {
+            String[] vals = s.split(",");
+            for (String val : vals) {
+                switch (val.toLowerCase(Locale.US)) {
+                    case "errors":
+                        logging |= ERRORS;
+                        break;
+                    case "requests":
+                        logging |= REQUESTS;
+                        break;
+                    case "headers":
+                        logging |= HEADERS;
+                        break;
+                    case "content":
+                        logging |= CONTENT;
+                        break;
+                    case "ssl":
+                        logging |= SSL;
+                        break;
+                    case "trace":
+                        logging |= TRACE;
+                        break;
+                    case "all":
+                        logging |= CONTENT|HEADERS|REQUESTS|FRAMES|ERRORS|TRACE|SSL;
+                        break;
+                }
+                if (val.startsWith("frames")) {
+                    logging |= FRAMES;
+                    String[] types = val.split(":");
+                    if (types.length == 1) {
+                        frametypes = CONTROL | DATA | WINDOW_UPDATES;
+                    } else {
+                        for (String type : types) {
+                            switch (type.toLowerCase()) {
+                                case "control":
+                                    frametypes |= CONTROL;
+                                    break;
+                                case "data":
+                                    frametypes |= DATA;
+                                    break;
+                                case "window":
+                                    frametypes |= WINDOW_UPDATES;
+                                    break;
+                                case "all":
+                                    frametypes = ALL;
+                                    break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (logging != OFF) {
+            logger = System.getLogger("jdk.httpclient.HttpClient");
+        } else {
+            logger = null;
+        }
+    }
+    public static boolean errors() {
+        return (logging & ERRORS) != 0;
+    }
+
+    public static boolean requests() {
+        return (logging & REQUESTS) != 0;
+    }
+
+    public static boolean headers() {
+        return (logging & HEADERS) != 0;
+    }
+
+    public static boolean trace() {
+        return (logging & TRACE) != 0;
+    }
+
+    public static boolean ssl() {
+        return (logging & SSL) != 0;
+    }
+
+    public static boolean frames() {
+        return (logging & FRAMES) != 0;
+    }
+
+    public static void logError(String s, Object... s1) {
+        if (errors()) {
+            logger.log(Level.INFO, "ERROR: " + s, s1);
+        }
+    }
+
+    public static void logError(Throwable t) {
+        if (errors()) {
+            String s = Utils.stackTrace(t);
+            logger.log(Level.INFO, "ERROR: " + s);
+        }
+    }
+
+    public static void logSSL(String s, Object... s1) {
+        if (ssl()) {
+            logger.log(Level.INFO, "SSL: " + s, s1);
+        }
+    }
+
+    public static void logSSL(Supplier<String> msgSupplier) {
+        if (ssl()) {
+            logger.log(Level.INFO, "SSL: " + msgSupplier.get());
+        }
+    }
+
+    public static void logTrace(String s, Object... s1) {
+        if (trace()) {
+            String format = "TRACE: " + s;
+            logger.log(Level.INFO, format, s1);
+        }
+    }
+
+    public static void logRequest(String s, Object... s1) {
+        if (requests()) {
+            logger.log(Level.INFO, "REQUEST: " + s, s1);
+        }
+    }
+
+    public static void logResponse(String s, Object... s1) {
+        if (requests()) {
+            logger.log(Level.INFO, "RESPONSE: " + s, s1);
+        }
+    }
+
+    public static void logHeaders(String s, Object... s1) {
+        if (headers()) {
+            logger.log(Level.INFO, "HEADERS: " + s, s1);
+        }
+    }
+
+    public static boolean loggingFrame(Class<? extends Http2Frame> clazz) {
+        if (frametypes == ALL) {
+            return true;
+        }
+        if (clazz == DataFrame.class) {
+            return (frametypes & DATA) != 0;
+        } else if (clazz == WindowUpdateFrame.class) {
+            return (frametypes & WINDOW_UPDATES) != 0;
+        } else {
+            return (frametypes & CONTROL) != 0;
+        }
+    }
+
+    public static void logFrames(Http2Frame f, String direction) {
+        if (frames() && loggingFrame(f.getClass())) {
+            logger.log(Level.INFO, "FRAME: " + direction + ": " + f.toString());
+        }
+    }
+
+    public static void dumpHeaders(StringBuilder sb, String prefix, HttpHeaders headers) {
+        if (headers != null) {
+            Map<String,List<String>> h = headers.map();
+            Set<Map.Entry<String,List<String>>> entries = h.entrySet();
+            for (Map.Entry<String,List<String>> entry : entries) {
+                String key = entry.getKey();
+                List<String> values = entry.getValue();
+                sb.append(prefix).append(key).append(":");
+                for (String value : values) {
+                    sb.append(' ').append(value);
+                }
+                sb.append('\n');
+            }
+        }
+    }
+
+
+    // not instantiable
+    private Log() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/MinimalFuture.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http.internal.common;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import static java.util.Objects.requireNonNull;
+import java.util.concurrent.atomic.AtomicLong;
+
+/*
+ * A CompletableFuture which does not allow any obtrusion logic.
+ * All methods of CompletionStage return instances of this class.
+ */
+public final class MinimalFuture<T> extends CompletableFuture<T> {
+
+    final static AtomicLong TOKENS = new AtomicLong();
+    final long id;
+
+    public static <U> MinimalFuture<U> completedFuture(U value) {
+        MinimalFuture<U> f = new MinimalFuture<>();
+        f.complete(value);
+        return f;
+    }
+
+    public static <U> CompletableFuture<U> failedFuture(Throwable ex) {
+        requireNonNull(ex);
+        MinimalFuture<U> f = new MinimalFuture<>();
+        f.completeExceptionally(ex);
+        return f;
+    }
+
+    public MinimalFuture() {
+        super();
+        this.id = TOKENS.incrementAndGet();
+    }
+
+    /**
+     * Creates a defensive copy of the given {@code CompletionStage}.
+     *
+     * <p> Might be useful both for producers and consumers of {@code
+     * CompletionStage}s.
+     *
+     * <p> Producers are protected from possible uncontrolled modifications
+     * (cancellation, completion, obtrusion, etc.) as well as from executing
+     * unknown potentially lengthy or faulty dependants in the given {@code
+     * CompletionStage}'s default execution facility or synchronously.
+     *
+     * <p> Consumers are protected from some of the aspects of misbehaving
+     * implementations (e.g. accepting results, applying functions, running
+     * tasks, etc. more than once or escape of a reference to their private
+     * executor, etc.) by providing a reliable proxy they use instead.
+     *
+     * @param src
+     *         the {@code CompletionStage} to make a copy from
+     * @param executor
+     *         the executor used to propagate the completion
+     * @param <T>
+     *         the type of the {@code CompletionStage}'s result
+     *
+     * @return a copy of the given stage
+     */
+    public static <T> MinimalFuture<T> copy(CompletionStage<T> src,
+                                            Executor executor) {
+        MinimalFuture<T> copy = new MinimalFuture<>();
+        BiConsumer<T, Throwable> relay =
+                (result, error) -> {
+                    if (error != null) {
+                        copy.completeExceptionally(error);
+                    } else {
+                        copy.complete(result);
+                    }
+                };
+
+        if (src.getClass() == CompletableFuture.class) {
+            // No subclasses! Strictly genuine CompletableFuture.
+            src.whenCompleteAsync(relay, executor);
+            return copy;
+        } else {
+            // Don't give our executor away to an unknown CS!
+            src.whenComplete(relay);
+            return (MinimalFuture<T>)
+                    copy.thenApplyAsync(Function.identity(), executor);
+        }
+    }
+
+    @Override
+    public <U> MinimalFuture<U> newIncompleteFuture() {
+        return new MinimalFuture<>();
+    }
+
+    @Override
+    public void obtrudeValue(T value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void obtrudeException(Throwable ex) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " (id=" + id +")";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Pair.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.common;
+
+/**
+ * A simple paired value class
+ */
+public final class Pair<T, U> {
+
+    public Pair(T first, U second) {
+        this.second = second;
+        this.first = first;
+    }
+
+    public final T first;
+    public final U second;
+
+    // Because 'pair()' is shorter than 'new Pair<>()'.
+    // Sometimes this difference might be very significant (especially in a
+    // 80-ish characters boundary). Sorry diamond operator.
+    public static <T, U> Pair<T, U> pair(T first, U second) {
+        return new Pair<>(first, second);
+    }
+
+    @Override
+    public String toString() {
+        return "(" + first + ", " + second + ")";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Queue.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.common;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.stream.Stream;
+
+// Each stream has one of these for input. Each Http2Connection has one
+// for output. Can be used blocking or asynchronously.
+
+public class Queue<T> implements ExceptionallyCloseable  {
+
+    private final LinkedList<T> q = new LinkedList<>();
+    private volatile boolean closed = false;
+    private volatile Throwable exception = null;
+    private Runnable callback;
+    private boolean forceCallback;
+    private int waiters; // true if someone waiting
+
+    public synchronized void putAll(T[] objs) throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+        boolean wasEmpty = q.isEmpty();
+
+        for (T obj : objs) {
+            q.add(obj);
+        }
+
+        if (waiters > 0) {
+            notifyAll();
+        }
+
+        if (wasEmpty || forceCallback) {
+            forceCallback = false;
+            if (callback != null) {
+                // Note: calling callback while holding the lock is
+                // dangerous and may lead to deadlocks.
+                callback.run();
+           }
+        }
+    }
+
+    public synchronized int size() {
+        return q.size();
+    }
+
+    public synchronized boolean tryPut(T obj) throws IOException {
+        if (closed) return false;
+        put(obj);
+        return true;
+    }
+
+    public synchronized void put(T obj) throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+
+        q.add(obj);
+        if (waiters > 0) {
+            notifyAll();
+        }
+
+        if (q.size() == 1 || forceCallback) {
+            forceCallback = false;
+            if (callback != null) {
+                // Note: calling callback while holding the lock is
+                // dangerous and may lead to deadlocks.
+                callback.run();
+            }
+        }
+    }
+
+    /**
+     * callback is invoked any time put is called where
+     * the Queue was empty.
+     */
+    public synchronized void registerPutCallback(Runnable callback) {
+        this.callback = callback;
+        if (callback != null && q.size() > 0) {
+            // Note: calling callback while holding the lock is
+            // dangerous and may lead to deadlocks.
+            callback.run();
+        }
+    }
+
+    @Override
+    public synchronized void close() {
+        closed = true;
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void closeExceptionally(Throwable t) {
+        if (exception == null) exception = t;
+        else if (t != null && t != exception) {
+            Stream.of(exception.getSuppressed())
+                .filter(x -> x == t)
+                .findFirst()
+                .ifPresentOrElse((x) -> {},
+                                 () -> exception.addSuppressed(t));
+        }
+        close();
+    }
+
+    public synchronized T take() throws IOException {
+        if (closed) {
+            throw newIOException("stream closed");
+        }
+        try {
+            while (q.size() == 0) {
+                waiters++;
+                wait();
+                if (closed) {
+                    throw newIOException("Queue closed");
+                }
+                waiters--;
+            }
+            return q.removeFirst();
+        } catch (InterruptedException ex) {
+            throw new IOException(ex);
+        }
+    }
+
+    public synchronized T poll() throws IOException {
+        if (closed) {
+            throw newIOException("stream closed");
+        }
+
+        if (q.isEmpty()) {
+            return null;
+        }
+        T res = q.removeFirst();
+        return res;
+    }
+
+    public synchronized T[] pollAll(T[] type) throws IOException {
+        T[] ret = q.toArray(type);
+        q.clear();
+        return ret;
+    }
+
+    public synchronized void pushback(T v) {
+        forceCallback = true;
+        q.addFirst(v);
+    }
+
+    public synchronized void pushbackAll(T[] v) {
+        forceCallback = true;
+        for (int i=v.length-1; i>=0; i--) {
+            q.addFirst(v[i]);
+        }
+    }
+
+    private IOException newIOException(String msg) {
+        if (exception == null) {
+            return new IOException(msg);
+        } else {
+            return new IOException(msg, exception);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Utils.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.common;
+
+import jdk.internal.misc.InnocuousThread;
+import sun.net.NetProperties;
+
+import javax.net.ssl.SSLParameters;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.net.NetPermission;
+import java.net.URI;
+import java.net.URLPermission;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.function.Predicate;
+
+/**
+ * Miscellaneous utilities
+ */
+public final class Utils {
+
+    /**
+     * Allocated buffer size. Must never be higher than 16K. But can be lower
+     * if smaller allocation units preferred. HTTP/2 mandates that all
+     * implementations support frame payloads of at least 16K.
+     */
+    public static final int DEFAULT_BUFSIZE = 16 * 1024;
+
+    public static final int BUFSIZE = getIntegerNetProperty(
+            "jdk.httpclient.bufsize", DEFAULT_BUFSIZE
+    );
+
+    private static final Set<String> DISALLOWED_HEADERS_SET = Set.of(
+            "authorization", "connection", "cookie", "content-length",
+            "date", "expect", "from", "host", "origin", "proxy-authorization",
+            "referer", "user-agent", "upgrade", "via", "warning");
+
+    public static final Predicate<String>
+        ALLOWED_HEADERS = header -> !Utils.DISALLOWED_HEADERS_SET.contains(header);
+
+    public static final Predicate<String>
+        ALL_HEADERS = header -> true;
+
+    public static ByteBuffer getBuffer() {
+        return ByteBuffer.allocate(BUFSIZE);
+    }
+
+    public static IOException getIOException(Throwable t) {
+        if (t instanceof IOException) {
+            return (IOException) t;
+        }
+        Throwable cause = t.getCause();
+        if (cause != null) {
+            return getIOException(cause);
+        }
+        return new IOException(t);
+    }
+
+    /**
+     * We use the same buffer for reading all headers and dummy bodies in an Exchange.
+     */
+    public static ByteBuffer getExchangeBuffer() {
+        ByteBuffer buf = getBuffer();
+        // Force a read the first time it is used
+        buf.limit(0);
+        return buf;
+    }
+
+    /**
+     * Puts position to limit and limit to capacity so we can resume reading
+     * into this buffer, but if required > 0 then limit may be reduced so that
+     * no more than required bytes are read next time.
+     */
+    static void resumeChannelRead(ByteBuffer buf, int required) {
+        int limit = buf.limit();
+        buf.position(limit);
+        int capacity = buf.capacity() - limit;
+        if (required > 0 && required < capacity) {
+            buf.limit(limit + required);
+        } else {
+            buf.limit(buf.capacity());
+        }
+    }
+
+    private Utils() { }
+
+    public static ExecutorService innocuousThreadPool() {
+        return Executors.newCachedThreadPool(
+                (r) -> InnocuousThread.newThread("DefaultHttpClient", r));
+    }
+
+    // ABNF primitives defined in RFC 7230
+    private static final boolean[] tchar      = new boolean[256];
+    private static final boolean[] fieldvchar = new boolean[256];
+
+    static {
+        char[] allowedTokenChars =
+                ("!#$%&'*+-.^_`|~0123456789" +
+                 "abcdefghijklmnopqrstuvwxyz" +
+                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
+        for (char c : allowedTokenChars) {
+            tchar[c] = true;
+        }
+        for (char c = 0x21; c < 0xFF; c++) {
+            fieldvchar[c] = true;
+        }
+        fieldvchar[0x7F] = false; // a little hole (DEL) in the range
+    }
+
+    /*
+     * Validates a RFC 7230 field-name.
+     */
+    public static boolean isValidName(String token) {
+        for (int i = 0; i < token.length(); i++) {
+            char c = token.charAt(i);
+            if (c > 255 || !tchar[c]) {
+                return false;
+            }
+        }
+        return !token.isEmpty();
+    }
+
+    /*
+     * Validates a RFC 7230 field-value.
+     *
+     * "Obsolete line folding" rule
+     *
+     *     obs-fold = CRLF 1*( SP / HTAB )
+     *
+     * is not permitted!
+     */
+    public static boolean isValidValue(String token) {
+        boolean accepted = true;
+        for (int i = 0; i < token.length(); i++) {
+            char c = token.charAt(i);
+            if (c > 255) {
+                return false;
+            }
+            if (accepted) {
+                if (c == ' ' || c == '\t') {
+                    accepted = false;
+                } else if (!fieldvchar[c]) {
+                    return false; // forbidden byte
+                }
+            } else {
+                if (c != ' ' && c != '\t') {
+                    if (fieldvchar[c]) {
+                        accepted = true;
+                    } else {
+                        return false; // forbidden byte
+                    }
+                }
+            }
+        }
+        return accepted;
+    }
+
+    /**
+     * Returns the security permission required for the given details.
+     * If method is CONNECT, then uri must be of form "scheme://host:port"
+     */
+    public static URLPermission getPermission(URI uri,
+                                              String method,
+                                              Map<String, List<String>> headers) {
+        StringBuilder sb = new StringBuilder();
+
+        String urlstring, actionstring;
+
+        if (method.equals("CONNECT")) {
+            urlstring = uri.toString();
+            actionstring = "CONNECT";
+        } else {
+            sb.append(uri.getScheme())
+                    .append("://")
+                    .append(uri.getAuthority())
+                    .append(uri.getPath());
+            urlstring = sb.toString();
+
+            sb = new StringBuilder();
+            sb.append(method);
+            if (headers != null && !headers.isEmpty()) {
+                sb.append(':');
+                Set<String> keys = headers.keySet();
+                boolean first = true;
+                for (String key : keys) {
+                    if (!first) {
+                        sb.append(',');
+                    }
+                    sb.append(key);
+                    first = false;
+                }
+            }
+            actionstring = sb.toString();
+        }
+        return new URLPermission(urlstring, actionstring);
+    }
+
+    public static void checkNetPermission(String target) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            return;
+        }
+        NetPermission np = new NetPermission(target);
+        sm.checkPermission(np);
+    }
+
+    public static int getIntegerNetProperty(String name, int defaultValue) {
+        return AccessController.doPrivileged((PrivilegedAction<Integer>) () ->
+                NetProperties.getInteger(name, defaultValue));
+    }
+
+    static String getNetProperty(String name) {
+        return AccessController.doPrivileged((PrivilegedAction<String>) () ->
+                NetProperties.get(name));
+    }
+
+    public static SSLParameters copySSLParameters(SSLParameters p) {
+        SSLParameters p1 = new SSLParameters();
+        p1.setAlgorithmConstraints(p.getAlgorithmConstraints());
+        p1.setCipherSuites(p.getCipherSuites());
+        p1.setEnableRetransmissions(p.getEnableRetransmissions());
+        p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
+        p1.setMaximumPacketSize(p.getMaximumPacketSize());
+        p1.setNeedClientAuth(p.getNeedClientAuth());
+        String[] protocols = p.getProtocols();
+        if (protocols != null) {
+            p1.setProtocols(protocols.clone());
+        }
+        p1.setSNIMatchers(p.getSNIMatchers());
+        p1.setServerNames(p.getServerNames());
+        p1.setUseCipherSuitesOrder(p.getUseCipherSuitesOrder());
+        p1.setWantClientAuth(p.getWantClientAuth());
+        return p1;
+    }
+
+    /**
+     * Set limit to position, and position to mark.
+     */
+    public static void flipToMark(ByteBuffer buffer, int mark) {
+        buffer.limit(buffer.position());
+        buffer.position(mark);
+    }
+
+    public static String stackTrace(Throwable t) {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        String s = null;
+        try {
+            PrintStream p = new PrintStream(bos, true, "US-ASCII");
+            t.printStackTrace(p);
+            s = bos.toString("US-ASCII");
+        } catch (UnsupportedEncodingException ex) {
+            // can't happen
+        }
+        return s;
+    }
+
+    /**
+     * Copies as much of src to dst as possible.
+     * Return number of bytes copied
+     */
+    public static int copy(ByteBuffer src, ByteBuffer dst) {
+        int srcLen = src.remaining();
+        int dstLen = dst.remaining();
+        if (srcLen > dstLen) {
+            int diff = srcLen - dstLen;
+            int limit = src.limit();
+            src.limit(limit - diff);
+            dst.put(src);
+            src.limit(limit);
+        } else {
+            dst.put(src);
+        }
+        return srcLen - src.remaining();
+    }
+
+    // copy up to amount from src to dst, but no more
+    public static int copyUpTo(ByteBuffer src, ByteBuffer dst, int amount) {
+        int toCopy = Math.min(src.remaining(), Math.min(dst.remaining(), amount));
+        copy(src, dst, toCopy);
+        return toCopy;
+    }
+
+    /**
+     * Copy amount bytes from src to dst. at least amount must be
+     * available in both dst and in src
+     */
+    public static void copy(ByteBuffer src, ByteBuffer dst, int amount) {
+        int excess = src.remaining() - amount;
+        assert excess >= 0;
+        if (excess > 0) {
+            int srclimit = src.limit();
+            src.limit(srclimit - excess);
+            dst.put(src);
+            src.limit(srclimit);
+        } else {
+            dst.put(src);
+        }
+    }
+
+    public static ByteBuffer copy(ByteBuffer src) {
+        ByteBuffer dst = ByteBuffer.allocate(src.remaining());
+        dst.put(src);
+        dst.flip();
+        return dst;
+    }
+
+    public static String dump(Object... objects) {
+        return Arrays.toString(objects);
+    }
+
+    public static String stringOf(Collection<?> source) {
+        // We don't know anything about toString implementation of this
+        // collection, so let's create an array
+        return Arrays.toString(source.toArray());
+    }
+
+    public static int remaining(ByteBuffer[] bufs) {
+        int remain = 0;
+        for (ByteBuffer buf : bufs) {
+            remain += buf.remaining();
+        }
+        return remain;
+    }
+
+    public static int remaining(List<ByteBuffer> bufs) {
+        int remain = 0;
+        for (ByteBuffer buf : bufs) {
+            remain += buf.remaining();
+        }
+        return remain;
+    }
+
+    public static int remaining(ByteBufferReference[] refs) {
+        int remain = 0;
+        for (ByteBufferReference ref : refs) {
+            remain += ref.get().remaining();
+        }
+        return remain;
+    }
+
+    // assumes buffer was written into starting at position zero
+    static void unflip(ByteBuffer buf) {
+        buf.position(buf.limit());
+        buf.limit(buf.capacity());
+    }
+
+    public static void close(Closeable... closeables) {
+        for (Closeable c : closeables) {
+            try {
+                c.close();
+            } catch (IOException ignored) { }
+        }
+    }
+
+    public static void close(Throwable t, Closeable... closeables) {
+        for (Closeable c : closeables) {
+            try {
+                ExceptionallyCloseable.close(t, c);
+            } catch (IOException ignored) { }
+        }
+    }
+
+    /**
+     * Returns an array with the same buffers, but starting at position zero
+     * in the array.
+     */
+    public static ByteBuffer[] reduce(ByteBuffer[] bufs, int start, int number) {
+        if (start == 0 && number == bufs.length) {
+            return bufs;
+        }
+        ByteBuffer[] nbufs = new ByteBuffer[number];
+        int j = 0;
+        for (int i=start; i<start+number; i++) {
+            nbufs[j++] = bufs[i];
+        }
+        return nbufs;
+    }
+
+    static String asString(ByteBuffer buf) {
+        byte[] b = new byte[buf.remaining()];
+        buf.get(b);
+        return new String(b, StandardCharsets.US_ASCII);
+    }
+
+    /**
+     * Returns a single threaded executor which uses one invocation
+     * of the parent executor to execute tasks (in sequence).
+     *
+     * Use a null valued Runnable to terminate.
+     */
+    // TODO: this is a blocking way of doing this;
+    public static Executor singleThreadExecutor(Executor parent) {
+        BlockingQueue<Optional<Runnable>> queue = new LinkedBlockingQueue<>();
+        parent.execute(() -> {
+            while (true) {
+                try {
+                    Optional<Runnable> o = queue.take();
+                    if (!o.isPresent()) {
+                        return;
+                    }
+                    o.get().run();
+                } catch (InterruptedException ex) {
+                    return;
+                }
+            }
+        });
+        return new Executor() {
+            @Override
+            public void execute(Runnable command) {
+                queue.offer(Optional.ofNullable(command));
+            }
+        };
+    }
+
+    private static void executeInline(Runnable r) {
+        r.run();
+    }
+
+    static Executor callingThreadExecutor() {
+        return Utils::executeInline;
+    }
+
+    // Put all these static 'empty' singletons here
+    @SuppressWarnings("rawtypes")
+    public static final CompletableFuture[] EMPTY_CFARRAY = new CompletableFuture[0];
+
+    public static final ByteBuffer EMPTY_BYTEBUFFER = ByteBuffer.allocate(0);
+    public static final ByteBuffer[] EMPTY_BB_ARRAY = new ByteBuffer[0];
+
+    public static ByteBuffer slice(ByteBuffer buffer, int amount) {
+        ByteBuffer newb = buffer.slice();
+        newb.limit(amount);
+        buffer.position(buffer.position() + amount);
+        return newb;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/ContinuationFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+public class ContinuationFrame extends HeaderFrame {
+
+    public static final int TYPE = 0x9;
+
+    public ContinuationFrame(int streamid, int flags, ByteBufferReference[] headerBlocks) {
+        super(streamid, flags, headerBlocks);
+    }
+
+    public ContinuationFrame(int streamid, ByteBufferReference headersBlock) {
+        this(streamid, 0, new ByteBufferReference[]{headersBlock});
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return headerLength;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/DataFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+public class DataFrame extends Http2Frame {
+
+    public static final int TYPE = 0x0;
+
+    // Flags
+    public static final int END_STREAM = 0x1;
+    public static final int PADDED = 0x8;
+
+    private int padLength;
+    private final ByteBufferReference[] data;
+    private final int dataLength;
+
+    public DataFrame(int streamid, int flags, ByteBufferReference data) {
+        this(streamid, flags, new ByteBufferReference[]{data});
+    }
+
+    public DataFrame(int streamid, int flags, ByteBufferReference[] data) {
+        super(streamid, flags);
+        this.data = data;
+        this.dataLength = Utils.remaining(data);
+    }
+
+    public DataFrame(int streamid, int flags, ByteBufferReference[] data, int padLength) {
+        this(streamid, flags, data);
+        if (padLength > 0) {
+            setPadLength(padLength);
+        }
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return dataLength + (((flags & PADDED) != 0) ? (padLength + 1) : 0);
+    }
+
+    @Override
+    public String flagAsString(int flag) {
+        switch (flag) {
+        case END_STREAM:
+            return "END_STREAM";
+        case PADDED:
+            return "PADDED";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public ByteBufferReference[] getData() {
+        return data;
+    }
+
+    public int getDataLength() {
+        return dataLength;
+    }
+
+    int getPadLength() {
+        return padLength;
+    }
+
+    public void setPadLength(int padLength) {
+        this.padLength = padLength;
+        flags |= PADDED;
+    }
+
+    public int payloadLength() {
+        // RFC 7540 6.1:
+        // The entire DATA frame payload is included in flow control,
+        // including the Pad Length and Padding fields if present
+        if ((flags & PADDED) != 0) {
+            return dataLength + (1 + padLength);
+        } else {
+            return dataLength;
+        }
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/ErrorFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+public abstract class ErrorFrame extends Http2Frame {
+
+    // error codes
+    public static final int NO_ERROR = 0x0;
+    public static final int PROTOCOL_ERROR = 0x1;
+    public static final int INTERNAL_ERROR = 0x2;
+    public static final int FLOW_CONTROL_ERROR = 0x3;
+    public static final int SETTINGS_TIMEOUT = 0x4;
+    public static final int STREAM_CLOSED = 0x5;
+    public static final int FRAME_SIZE_ERROR = 0x6;
+    public static final int REFUSED_STREAM = 0x7;
+    public static final int CANCEL = 0x8;
+    public static final int COMPRESSION_ERROR = 0x9;
+    public static final int CONNECT_ERROR = 0xa;
+    public static final int ENHANCE_YOUR_CALM = 0xb;
+    public static final int INADEQUATE_SECURITY = 0xc;
+    public static final int HTTP_1_1_REQUIRED = 0xd;
+    static final int LAST_ERROR = 0xd;
+
+    static final String[] errorStrings = {
+        "Not an error",
+        "Protocol error",
+        "Internal error",
+        "Flow control error",
+        "Settings timeout",
+        "Stream is closed",
+        "Frame size error",
+        "Stream not processed",
+        "Stream cancelled",
+        "Compression state not updated",
+        "TCP Connection error on CONNECT",
+        "Processing capacity exceeded",
+        "Negotiated TLS parameters not acceptable",
+        "Use HTTP/1.1 for request"
+    };
+
+    public static String stringForCode(int code) {
+        if (code < 0) {
+            throw new IllegalArgumentException();
+        }
+
+        if (code > LAST_ERROR) {
+            return "Error: " + Integer.toString(code);
+        } else {
+            return errorStrings[code];
+        }
+    }
+
+    int errorCode;
+
+    public ErrorFrame(int streamid, int flags, int errorCode) {
+        super(streamid, flags);
+        this.errorCode = errorCode;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " Error: " + stringForCode(errorCode);
+    }
+
+    public int getErrorCode() {
+        return this.errorCode;
+    }
+
+    public void setErrorCode(int errorCode) {
+        this.errorCode = errorCode;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/FramesDecoder.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Log;
+import jdk.incubator.http.internal.common.Utils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Frames Decoder
+ * <p>
+ * collect buffers until frame decoding is possible,
+ * all decoded frames are passed to the FrameProcessor callback in order of decoding.
+ *
+ * It's a stateful class due to the fact that FramesDecoder stores buffers inside.
+ * Should be allocated only the single instance per connection.
+ */
+public class FramesDecoder {
+
+
+
+    @FunctionalInterface
+    public interface FrameProcessor {
+        void processFrame(Http2Frame frame) throws IOException;
+    }
+
+    private final FrameProcessor frameProcessor;
+    private final int maxFrameSize;
+
+    private ByteBufferReference currentBuffer; // current buffer either null or hasRemaining
+
+    private final java.util.Queue<ByteBufferReference> tailBuffers = new ArrayDeque<>();
+    private int tailSize = 0;
+
+    private boolean slicedToDataFrame = false;
+
+    private final List<ByteBufferReference> prepareToRelease = new ArrayList<>();
+
+    // if true  - Frame Header was parsed (9 bytes consumed) and subsequent fields have meaning
+    // otherwise - stopped at frames boundary
+    private boolean frameHeaderParsed = false;
+    private int frameLength;
+    private int frameType;
+    private int frameFlags;
+    private int frameStreamid;
+
+    /**
+     * Creates Frame Decoder
+     *
+     * @param frameProcessor - callback for decoded frames
+     */
+    public FramesDecoder(FrameProcessor frameProcessor) {
+        this(frameProcessor, 16 * 1024);
+    }
+
+    /**
+     * Creates Frame Decoder
+     * @param frameProcessor - callback for decoded frames
+     * @param maxFrameSize - maxFrameSize accepted by this decoder
+     */
+    public FramesDecoder(FrameProcessor frameProcessor, int maxFrameSize) {
+        this.frameProcessor = frameProcessor;
+        this.maxFrameSize = Math.min(Math.max(16 * 1024, maxFrameSize), 16 * 1024 * 1024 - 1);
+    }
+
+    /**
+     * put next buffer into queue,
+     * if frame decoding is possible - decode all buffers and invoke FrameProcessor
+     *
+     * @param buffer
+     * @throws IOException
+     */
+    public void decode(ByteBufferReference buffer) throws IOException {
+        int remaining = buffer.get().remaining();
+        if (remaining > 0) {
+            if (currentBuffer == null) {
+                currentBuffer = buffer;
+            } else {
+                tailBuffers.add(buffer);
+                tailSize += remaining;
+            }
+        }
+        Http2Frame frame;
+        while ((frame = nextFrame()) != null) {
+            frameProcessor.processFrame(frame);
+            frameProcessed();
+        }
+    }
+
+    private Http2Frame nextFrame() throws IOException {
+        while (true) {
+            if (currentBuffer == null) {
+                return null; // no data at all
+            }
+            if (!frameHeaderParsed) {
+                if (currentBuffer.get().remaining() + tailSize >= Http2Frame.FRAME_HEADER_SIZE) {
+                    parseFrameHeader();
+                    if (frameLength > maxFrameSize) {
+                        // connection error
+                        return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                                "Frame type("+frameType+") " +"length("+frameLength+") exceeds MAX_FRAME_SIZE("+ maxFrameSize+")");
+                    }
+                    frameHeaderParsed = true;
+                } else {
+                    return null; // no data for frame header
+                }
+            }
+            if ((frameLength == 0) ||
+                    (currentBuffer != null && currentBuffer.get().remaining() + tailSize >= frameLength)) {
+                Http2Frame frame = parseFrameBody();
+                frameHeaderParsed = false;
+                // frame == null means we have to skip this frame and try parse next
+                if (frame != null) {
+                    return frame;
+                }
+            } else {
+                return null;  // no data for the whole frame header
+            }
+        }
+    }
+
+    private void frameProcessed() {
+        prepareToRelease.forEach(ByteBufferReference::clear);
+        prepareToRelease.clear();
+    }
+
+    private void parseFrameHeader() throws IOException {
+        int x = getInt();
+        this.frameLength = x >> 8;
+        this.frameType = x & 0xff;
+        this.frameFlags = getByte();
+        this.frameStreamid = getInt() & 0x7fffffff;
+        // R: A reserved 1-bit field.  The semantics of this bit are undefined,
+        // MUST be ignored when receiving.
+    }
+
+    // move next buffer from tailBuffers to currentBuffer if required
+    private void nextBuffer() {
+        if (!currentBuffer.get().hasRemaining()) {
+            if (!slicedToDataFrame) {
+                prepareToRelease.add(currentBuffer);
+            }
+            slicedToDataFrame = false;
+            currentBuffer = tailBuffers.poll();
+            if (currentBuffer != null) {
+                tailSize -= currentBuffer.get().remaining();
+            }
+        }
+    }
+
+    public int getByte() {
+        ByteBuffer buf = currentBuffer.get();
+        int res = buf.get() & 0xff;
+        nextBuffer();
+        return res;
+    }
+
+    public int getShort() {
+        ByteBuffer buf = currentBuffer.get();
+        if (buf.remaining() >= 2) {
+            int res = buf.getShort() & 0xffff;
+            nextBuffer();
+            return res;
+        }
+        int val = getByte();
+        val = (val << 8) + getByte();
+        return val;
+    }
+
+    public int getInt() {
+        ByteBuffer buf = currentBuffer.get();
+        if (buf.remaining() >= 4) {
+            int res = buf.getInt();
+            nextBuffer();
+            return res;
+        }
+        int val = getByte();
+        val = (val << 8) + getByte();
+        val = (val << 8) + getByte();
+        val = (val << 8) + getByte();
+        return val;
+
+    }
+
+    public byte[] getBytes(int n) {
+        byte[] bytes = new byte[n];
+        int offset = 0;
+        while (n > 0) {
+            ByteBuffer buf = currentBuffer.get();
+            int length = Math.min(n, buf.remaining());
+            buf.get(bytes, offset, length);
+            offset += length;
+            n -= length;
+            nextBuffer();
+        }
+        return bytes;
+
+    }
+
+    private ByteBufferReference[] getBuffers(boolean isDataFrame, int bytecount) {
+        List<ByteBufferReference> res = new ArrayList<>();
+        while (bytecount > 0) {
+            ByteBuffer buf = currentBuffer.get();
+            int remaining = buf.remaining();
+            int extract = Math.min(remaining, bytecount);
+            ByteBuffer extractedBuf;
+            if (isDataFrame) {
+                extractedBuf = Utils.slice(buf, extract);
+                slicedToDataFrame = true;
+            } else {
+                // Header frames here
+                // HPACK decoding should performed under lock and immediately after frame decoding.
+                // in that case it is safe to release original buffer,
+                // because of sliced buffer has a very short life
+                extractedBuf = Utils.slice(buf, extract);
+            }
+            res.add(ByteBufferReference.of(extractedBuf));
+            bytecount -= extract;
+            nextBuffer();
+        }
+        return res.toArray(new ByteBufferReference[0]);
+    }
+
+    public void skipBytes(int bytecount) {
+        while (bytecount > 0) {
+            ByteBuffer buf = currentBuffer.get();
+            int remaining = buf.remaining();
+            int extract = Math.min(remaining, bytecount);
+            buf.position(buf.position() + extract);
+            bytecount -= remaining;
+            nextBuffer();
+        }
+    }
+
+    private Http2Frame parseFrameBody() throws IOException {
+        assert frameHeaderParsed;
+        switch (frameType) {
+            case DataFrame.TYPE:
+                return parseDataFrame(frameLength, frameStreamid, frameFlags);
+            case HeadersFrame.TYPE:
+                return parseHeadersFrame(frameLength, frameStreamid, frameFlags);
+            case PriorityFrame.TYPE:
+                return parsePriorityFrame(frameLength, frameStreamid, frameFlags);
+            case ResetFrame.TYPE:
+                return parseResetFrame(frameLength, frameStreamid, frameFlags);
+            case SettingsFrame.TYPE:
+                return parseSettingsFrame(frameLength, frameStreamid, frameFlags);
+            case PushPromiseFrame.TYPE:
+                return parsePushPromiseFrame(frameLength, frameStreamid, frameFlags);
+            case PingFrame.TYPE:
+                return parsePingFrame(frameLength, frameStreamid, frameFlags);
+            case GoAwayFrame.TYPE:
+                return parseGoAwayFrame(frameLength, frameStreamid, frameFlags);
+            case WindowUpdateFrame.TYPE:
+                return parseWindowUpdateFrame(frameLength, frameStreamid, frameFlags);
+            case ContinuationFrame.TYPE:
+                return parseContinuationFrame(frameLength, frameStreamid, frameFlags);
+            default:
+                // RFC 7540 4.1
+                // Implementations MUST ignore and discard any frame that has a type that is unknown.
+                Log.logTrace("Unknown incoming frame type: {0}", frameType);
+                skipBytes(frameLength);
+                return null;
+        }
+    }
+
+    private Http2Frame parseDataFrame(int frameLength, int streamid, int flags) {
+        // non-zero stream
+        if (streamid == 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR, "zero streamId for DataFrame");
+        }
+        int padLength = 0;
+        if ((flags & DataFrame.PADDED) != 0) {
+            padLength = getByte();
+            if(padLength >= frameLength) {
+                return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                        "the length of the padding is the length of the frame payload or greater");
+            }
+            frameLength--;
+        }
+        DataFrame df = new DataFrame(streamid, flags,
+                getBuffers(true, frameLength - padLength), padLength);
+        skipBytes(padLength);
+        return df;
+
+    }
+
+    private Http2Frame parseHeadersFrame(int frameLength, int streamid, int flags) {
+        // non-zero stream
+        if (streamid == 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR, "zero streamId for HeadersFrame");
+        }
+        int padLength = 0;
+        if ((flags & HeadersFrame.PADDED) != 0) {
+            padLength = getByte();
+            frameLength--;
+        }
+        boolean hasPriority = (flags & HeadersFrame.PRIORITY) != 0;
+        boolean exclusive = false;
+        int streamDependency = 0;
+        int weight = 0;
+        if (hasPriority) {
+            int x = getInt();
+            exclusive = (x & 0x80000000) != 0;
+            streamDependency = x & 0x7fffffff;
+            weight = getByte();
+            frameLength -= 5;
+        }
+        if(frameLength < padLength) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "Padding exceeds the size remaining for the header block");
+        }
+        HeadersFrame hf = new HeadersFrame(streamid, flags,
+                getBuffers(false, frameLength - padLength), padLength);
+        skipBytes(padLength);
+        if (hasPriority) {
+            hf.setPriority(streamDependency, exclusive, weight);
+        }
+        return hf;
+    }
+
+    private Http2Frame parsePriorityFrame(int frameLength, int streamid, int flags) {
+        // non-zero stream; no flags
+        if (streamid == 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "zero streamId for PriorityFrame");
+        }
+        if(frameLength != 5) {
+            skipBytes(frameLength);
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR, streamid,
+                    "PriorityFrame length is "+ frameLength+", expected 5");
+        }
+        int x = getInt();
+        int weight = getByte();
+        return new PriorityFrame(streamid, x & 0x7fffffff, (x & 0x80000000) != 0, weight);
+    }
+
+    private Http2Frame parseResetFrame(int frameLength, int streamid, int flags) {
+        // non-zero stream; no flags
+        if (streamid == 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "zero streamId for ResetFrame");
+        }
+        if(frameLength != 4) {
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                    "ResetFrame length is "+ frameLength+", expected 4");
+        }
+        return new ResetFrame(streamid, getInt());
+    }
+
+    private Http2Frame parseSettingsFrame(int frameLength, int streamid, int flags) {
+        // only zero stream
+        if (streamid != 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "non-zero streamId for SettingsFrame");
+        }
+        if ((SettingsFrame.ACK & flags) != 0 && frameLength > 0) {
+            // RFC 7540 6.5
+            // Receipt of a SETTINGS frame with the ACK flag set and a length
+            // field value other than 0 MUST be treated as a connection error
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                    "ACK SettingsFrame is not empty");
+        }
+        if (frameLength % 6 != 0) {
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                    "invalid SettingsFrame size: "+frameLength);
+        }
+        SettingsFrame sf = new SettingsFrame(flags);
+        int n = frameLength / 6;
+        for (int i=0; i<n; i++) {
+            int id = getShort();
+            int val = getInt();
+            if (id > 0 && id <= SettingsFrame.MAX_PARAM) {
+                // a known parameter. Ignore otherwise
+                sf.setParameter(id, val); // TODO parameters validation
+            }
+        }
+        return sf;
+    }
+
+    private Http2Frame parsePushPromiseFrame(int frameLength, int streamid, int flags) {
+        // non-zero stream
+        if (streamid == 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "zero streamId for PushPromiseFrame");
+        }
+        int padLength = 0;
+        if ((flags & PushPromiseFrame.PADDED) != 0) {
+            padLength = getByte();
+            frameLength--;
+        }
+        int promisedStream = getInt() & 0x7fffffff;
+        frameLength -= 4;
+        if(frameLength < padLength) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "Padding exceeds the size remaining for the PushPromiseFrame");
+        }
+        PushPromiseFrame ppf = new PushPromiseFrame(streamid, flags, promisedStream,
+                getBuffers(false, frameLength - padLength), padLength);
+        skipBytes(padLength);
+        return ppf;
+    }
+
+    private Http2Frame parsePingFrame(int frameLength, int streamid, int flags) {
+        // only zero stream
+        if (streamid != 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "non-zero streamId for PingFrame");
+        }
+        if(frameLength != 8) {
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                    "PingFrame length is "+ frameLength+", expected 8");
+        }
+        return new PingFrame(flags, getBytes(8));
+    }
+
+    private Http2Frame parseGoAwayFrame(int frameLength, int streamid, int flags) {
+        // only zero stream; no flags
+        if (streamid != 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "non-zero streamId for GoAwayFrame");
+        }
+        if (frameLength < 8) {
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                    "Invalid GoAway frame size");
+        }
+        int lastStream = getInt() & 0x7fffffff;
+        int errorCode = getInt();
+        byte[] debugData = getBytes(frameLength - 8);
+        if (debugData.length > 0) {
+            Log.logError("GoAway debugData " + new String(debugData));
+        }
+        return new GoAwayFrame(lastStream, errorCode, debugData);
+    }
+
+    private Http2Frame parseWindowUpdateFrame(int frameLength, int streamid, int flags) {
+        // any stream; no flags
+        if(frameLength != 4) {
+            return new MalformedFrame(ErrorFrame.FRAME_SIZE_ERROR,
+                    "WindowUpdateFrame length is "+ frameLength+", expected 4");
+        }
+        return new WindowUpdateFrame(streamid, getInt() & 0x7fffffff);
+    }
+
+    private Http2Frame parseContinuationFrame(int frameLength, int streamid, int flags) {
+        // non-zero stream;
+        if (streamid == 0) {
+            return new MalformedFrame(ErrorFrame.PROTOCOL_ERROR,
+                    "zero streamId for ContinuationFrame");
+        }
+        return new ContinuationFrame(streamid, flags, getBuffers(false, frameLength));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/FramesEncoder.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Frames Encoder
+ *
+ * Encode framed into ByteBuffers.
+ * The class is stateless.
+ */
+public class FramesEncoder {
+
+
+    public FramesEncoder() {
+    }
+
+    public ByteBufferReference[] encodeFrames(List<HeaderFrame> frames) {
+        List<ByteBufferReference> refs = new ArrayList<>(frames.size() * 2);
+        for (HeaderFrame f : frames) {
+            refs.addAll(Arrays.asList(encodeFrame(f)));
+        }
+        return refs.toArray(new ByteBufferReference[0]);
+    }
+
+    public ByteBufferReference encodeConnectionPreface(byte[] preface, SettingsFrame frame) {
+        final int length = frame.length();
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length + preface.length);
+        ByteBuffer buf = ref.get();
+        buf.put(preface);
+        putSettingsFrame(buf, frame, length);
+        buf.flip();
+        return ref;
+    }
+
+    public ByteBufferReference[] encodeFrame(Http2Frame frame) {
+        switch (frame.type()) {
+            case DataFrame.TYPE:
+                return encodeDataFrame((DataFrame) frame);
+            case HeadersFrame.TYPE:
+                return encodeHeadersFrame((HeadersFrame) frame);
+            case PriorityFrame.TYPE:
+                return encodePriorityFrame((PriorityFrame) frame);
+            case ResetFrame.TYPE:
+                return encodeResetFrame((ResetFrame) frame);
+            case SettingsFrame.TYPE:
+                return encodeSettingsFrame((SettingsFrame) frame);
+            case PushPromiseFrame.TYPE:
+                return encodePushPromiseFrame((PushPromiseFrame) frame);
+            case PingFrame.TYPE:
+                return encodePingFrame((PingFrame) frame);
+            case GoAwayFrame.TYPE:
+                return encodeGoAwayFrame((GoAwayFrame) frame);
+            case WindowUpdateFrame.TYPE:
+                return encodeWindowUpdateFrame((WindowUpdateFrame) frame);
+            case ContinuationFrame.TYPE:
+                return encodeContinuationFrame((ContinuationFrame) frame);
+            default:
+                throw new UnsupportedOperationException("Not supported frame "+frame.type()+" ("+frame.getClass().getName()+")");
+        }
+    }
+
+    private static final int NO_FLAGS = 0;
+    private static final int ZERO_STREAM = 0;
+
+    private ByteBufferReference[] encodeDataFrame(DataFrame frame) {
+        // non-zero stream
+        assert frame.streamid() != 0;
+        ByteBufferReference ref = encodeDataFrameStart(frame);
+        if (frame.getFlag(DataFrame.PADDED)) {
+            return joinWithPadding(ref, frame.getData(), frame.getPadLength());
+        } else {
+            return join(ref, frame.getData());
+        }
+    }
+
+    private ByteBufferReference encodeDataFrameStart(DataFrame frame) {
+        boolean isPadded = frame.getFlag(DataFrame.PADDED);
+        final int length = frame.getDataLength() + (isPadded ? (frame.getPadLength() + 1) : 0);
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + (isPadded ? 1 : 0));
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, DataFrame.TYPE, frame.getFlags(), frame.streamid());
+        if (isPadded) {
+            buf.put((byte) frame.getPadLength());
+        }
+        buf.flip();
+        return ref;
+    }
+
+    private ByteBufferReference[] encodeHeadersFrame(HeadersFrame frame) {
+        // non-zero stream
+        assert frame.streamid() != 0;
+        ByteBufferReference ref = encodeHeadersFrameStart(frame);
+        if (frame.getFlag(HeadersFrame.PADDED)) {
+            return joinWithPadding(ref, frame.getHeaderBlock(), frame.getPadLength());
+        } else {
+            return join(ref, frame.getHeaderBlock());
+        }
+    }
+
+    private ByteBufferReference encodeHeadersFrameStart(HeadersFrame frame) {
+        boolean isPadded = frame.getFlag(HeadersFrame.PADDED);
+        boolean hasPriority = frame.getFlag(HeadersFrame.PRIORITY);
+        final int length = frame.getHeaderLength() + (isPadded ? (frame.getPadLength() + 1) : 0) + (hasPriority ? 5 : 0);
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + (isPadded ? 1 : 0) + (hasPriority ? 5 : 0));
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, HeadersFrame.TYPE, frame.getFlags(), frame.streamid());
+        if (isPadded) {
+            buf.put((byte) frame.getPadLength());
+        }
+        if (hasPriority) {
+            putPriority(buf, frame.getExclusive(), frame.getStreamDependency(), frame.getWeight());
+        }
+        buf.flip();
+        return ref;
+    }
+
+    private ByteBufferReference[] encodePriorityFrame(PriorityFrame frame) {
+        // non-zero stream; no flags
+        assert frame.streamid() != 0;
+        final int length = 5;
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length);
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, PriorityFrame.TYPE, NO_FLAGS, frame.streamid());
+        putPriority(buf, frame.exclusive(), frame.streamDependency(), frame.weight());
+        buf.flip();
+        return new ByteBufferReference[]{ref};
+    }
+
+    private ByteBufferReference[] encodeResetFrame(ResetFrame frame) {
+        // non-zero stream; no flags
+        assert frame.streamid() != 0;
+        final int length = 4;
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length);
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, ResetFrame.TYPE, NO_FLAGS, frame.streamid());
+        buf.putInt(frame.getErrorCode());
+        buf.flip();
+        return new ByteBufferReference[]{ref};
+    }
+
+    private ByteBufferReference[] encodeSettingsFrame(SettingsFrame frame) {
+        // only zero stream
+        assert frame.streamid() == 0;
+        final int length = frame.length();
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length);
+        ByteBuffer buf = ref.get();
+        putSettingsFrame(buf, frame, length);
+        buf.flip();
+        return new ByteBufferReference[]{ref};
+    }
+
+    private ByteBufferReference[] encodePushPromiseFrame(PushPromiseFrame frame) {
+        // non-zero stream
+        assert frame.streamid() != 0;
+        boolean isPadded = frame.getFlag(PushPromiseFrame.PADDED);
+        final int length = frame.getHeaderLength() + (isPadded ? 5 : 4);
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + (isPadded ? 5 : 4));
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, PushPromiseFrame.TYPE, frame.getFlags(), frame.streamid());
+        if (isPadded) {
+            buf.put((byte) frame.getPadLength());
+        }
+        buf.putInt(frame.getPromisedStream());
+        buf.flip();
+
+        if (frame.getFlag(PushPromiseFrame.PADDED)) {
+            return joinWithPadding(ref, frame.getHeaderBlock(), frame.getPadLength());
+        } else {
+            return join(ref, frame.getHeaderBlock());
+        }
+    }
+
+    private ByteBufferReference[] encodePingFrame(PingFrame frame) {
+        // only zero stream
+        assert frame.streamid() == 0;
+        final int length = 8;
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length);
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, PingFrame.TYPE, frame.getFlags(), ZERO_STREAM);
+        buf.put(frame.getData());
+        buf.flip();
+        return new ByteBufferReference[]{ref};
+    }
+
+    private ByteBufferReference[] encodeGoAwayFrame(GoAwayFrame frame) {
+        // only zero stream; no flags
+        assert frame.streamid() == 0;
+        byte[] debugData = frame.getDebugData();
+        final int length = 8 + debugData.length;
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length);
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, GoAwayFrame.TYPE, NO_FLAGS, ZERO_STREAM);
+        buf.putInt(frame.getLastStream());
+        buf.putInt(frame.getErrorCode());
+        if (debugData.length > 0) {
+            buf.put(debugData);
+        }
+        buf.flip();
+        return new ByteBufferReference[]{ref};
+    }
+
+    private ByteBufferReference[] encodeWindowUpdateFrame(WindowUpdateFrame frame) {
+        // any stream; no flags
+        final int length = 4;
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE + length);
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, WindowUpdateFrame.TYPE, NO_FLAGS, frame.streamid);
+        buf.putInt(frame.getUpdate());
+        buf.flip();
+        return new ByteBufferReference[]{ref};
+    }
+
+    private ByteBufferReference[] encodeContinuationFrame(ContinuationFrame frame) {
+        // non-zero stream;
+        assert frame.streamid() != 0;
+        final int length = frame.getHeaderLength();
+        ByteBufferReference ref = getBuffer(Http2Frame.FRAME_HEADER_SIZE);
+        ByteBuffer buf = ref.get();
+        putHeader(buf, length, ContinuationFrame.TYPE, frame.getFlags(), frame.streamid());
+        buf.flip();
+        return join(ref, frame.getHeaderBlock());
+    }
+
+    private ByteBufferReference[] joinWithPadding(ByteBufferReference ref, ByteBufferReference[] data, int padLength) {
+        ByteBufferReference[] references = new ByteBufferReference[2 + data.length];
+        references[0] = ref;
+        System.arraycopy(data, 0, references, 1, data.length);
+        assert references[references.length - 1] == null;
+        references[references.length - 1] = getPadding(padLength);
+        return references;
+    }
+
+    private ByteBufferReference[] join(ByteBufferReference ref, ByteBufferReference[] data) {
+        ByteBufferReference[] references = new ByteBufferReference[1 + data.length];
+        references[0] = ref;
+        System.arraycopy(data, 0, references, 1, data.length);
+        return references;
+    }
+
+    private void putSettingsFrame(ByteBuffer buf, SettingsFrame frame, int length) {
+        // only zero stream;
+        assert frame.streamid() == 0;
+        putHeader(buf, length, SettingsFrame.TYPE, frame.getFlags(), ZERO_STREAM);
+        frame.toByteBuffer(buf);
+    }
+
+    private void putHeader(ByteBuffer buf, int length, int type, int flags, int streamId) {
+        int x = (length << 8) + type;
+        buf.putInt(x);
+        buf.put((byte) flags);
+        buf.putInt(streamId);
+    }
+
+    private void putPriority(ByteBuffer buf, boolean exclusive, int streamDependency, int weight) {
+        buf.putInt(exclusive ? (1 << 31) + streamDependency : streamDependency);
+        buf.put((byte) weight);
+    }
+
+    private ByteBufferReference getBuffer(int capacity) {
+        return ByteBufferReference.of(ByteBuffer.allocate(capacity));
+    }
+
+    public ByteBufferReference getPadding(int length) {
+        if (length > 255) {
+            throw new IllegalArgumentException("Padding too big");
+        }
+        return ByteBufferReference.of(ByteBuffer.allocate(length)); // zeroed!
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/GoAwayFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+public class GoAwayFrame extends ErrorFrame {
+
+    private final int lastStream;
+    private final byte[] debugData;
+
+    public static final int TYPE = 0x7;
+
+
+    public GoAwayFrame(int lastStream, int errorCode) {
+        this(lastStream, errorCode, new byte[0]);
+    }
+
+    public GoAwayFrame(int lastStream, int errorCode, byte[] debugData) {
+        super(0, 0, errorCode);
+        this.lastStream = lastStream;
+        this.debugData = debugData;
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return 8 + debugData.length;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " Debugdata: " + new String(debugData);
+    }
+
+    public int getLastStream() {
+        return this.lastStream;
+    }
+
+    public byte[] getDebugData() {
+        return debugData;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/HeaderFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Either a HeadersFrame or a ContinuationFrame
+ */
+public abstract class HeaderFrame extends Http2Frame {
+
+    final int headerLength;
+    final ByteBufferReference[] headerBlocks;
+
+    public static final int END_STREAM = 0x1;
+    public static final int END_HEADERS = 0x4;
+
+    public HeaderFrame(int streamid, int flags, ByteBufferReference headerBlock) {
+        this(streamid, flags, new ByteBufferReference[]{headerBlock});
+    }
+
+    public HeaderFrame(int streamid, int flags, ByteBufferReference[] headerBlocks) {
+        super(streamid, flags);
+        this.headerBlocks = headerBlocks;
+        this.headerLength = Utils.remaining(headerBlocks);
+    }
+
+    @Override
+    public String flagAsString(int flag) {
+        switch (flag) {
+            case END_HEADERS:
+                return "END_HEADERS";
+            case END_STREAM:
+                return "END_STREAM";
+        }
+        return super.flagAsString(flag);
+    }
+
+
+    public ByteBufferReference[] getHeaderBlock() {
+        return headerBlocks;
+    }
+
+    int getHeaderLength() {
+        return headerLength;
+    }
+
+    /**
+     * Returns true if this block is the final block of headers.
+     */
+    public boolean endHeaders() {
+        return getFlag(END_HEADERS);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/HeadersFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+public class HeadersFrame extends HeaderFrame {
+
+    public static final int TYPE = 0x1;
+
+    // Flags
+    public static final int END_STREAM = 0x1;
+    public static final int PADDED = 0x8;
+    public static final int PRIORITY = 0x20;
+
+
+    private int padLength;
+    private int streamDependency;
+    private int weight;
+    private boolean exclusive;
+
+    public HeadersFrame(int streamid, int flags, ByteBufferReference[] headerBlocks, int padLength) {
+        super(streamid, flags, headerBlocks);
+        if (padLength > 0) {
+            setPadLength(padLength);
+        }
+    }
+
+    public HeadersFrame(int streamid, int flags, ByteBufferReference[] headerBlocks) {
+        super(streamid, flags, headerBlocks);
+    }
+
+    public HeadersFrame(int streamid, int flags, ByteBufferReference headerBlock) {
+        this(streamid, flags, new ByteBufferReference[]{headerBlock});
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return headerLength
+                + ((flags & PADDED) != 0 ? (1 + padLength) : 0)
+                + ((flags & PRIORITY) != 0 ? 5 : 0);
+    }
+
+    @Override
+    public String flagAsString(int flag) {
+        switch (flag) {
+            case END_STREAM:
+                return "END_STREAM";
+            case PADDED:
+                return "PADDED";
+            case PRIORITY:
+                return "PRIORITY";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public void setPadLength(int padLength) {
+        this.padLength = padLength;
+        flags |= PADDED;
+    }
+
+    int getPadLength() {
+        return padLength;
+    }
+
+    public void setPriority(int streamDependency, boolean exclusive, int weight) {
+        this.streamDependency = streamDependency;
+        this.exclusive = exclusive;
+        this.weight = weight;
+        this.flags |= PRIORITY;
+    }
+
+    public int getStreamDependency() {
+        return streamDependency;
+    }
+
+    public int getWeight() {
+        return weight;
+    }
+
+    public boolean getExclusive() {
+        return exclusive;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/Http2Frame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+/**
+ * When sending a frame, the length field must be set in sub-class
+ * by calling computeLength()
+ */
+public abstract class Http2Frame {
+
+    public static final int FRAME_HEADER_SIZE = 9;
+
+    protected int streamid;
+    protected int flags;
+
+    public Http2Frame(int streamid, int flags) {
+        this.streamid = streamid;
+        this.flags = flags;
+    }
+
+    public int streamid() {
+        return streamid;
+    }
+
+    public void setFlag(int flag) {
+        flags |= flag;
+    }
+
+    public void setFlags(int flags) {
+        this.flags = flags;
+    }
+
+    public int getFlags() {
+        return flags;
+    }
+
+    public boolean getFlag(int flag) {
+        return (flags & flag) != 0;
+    }
+
+    public void clearFlag(int flag) {
+        flags &= 0xffffffff ^ flag;
+    }
+
+    public void streamid(int streamid) {
+        this.streamid = streamid;
+    }
+
+
+    public String typeAsString() {
+        return asString(type());
+    }
+
+    public int type() {
+        return -1; // Unknown type
+    }
+
+    int length() {
+        return -1; // Unknown length
+    }
+
+
+    public static String asString(int type) {
+        switch (type) {
+          case DataFrame.TYPE:
+            return "DATA";
+          case HeadersFrame.TYPE:
+            return "HEADERS";
+          case ContinuationFrame.TYPE:
+            return "CONTINUATION";
+          case ResetFrame.TYPE:
+            return "RESET";
+          case PriorityFrame.TYPE:
+            return "PRIORITY";
+          case SettingsFrame.TYPE:
+            return "SETTINGS";
+          case GoAwayFrame.TYPE:
+            return "GOAWAY";
+          case PingFrame.TYPE:
+            return "PING";
+          case PushPromiseFrame.TYPE:
+            return "PUSH_PROMISE";
+          case WindowUpdateFrame.TYPE:
+            return "WINDOW_UPDATE";
+          default:
+            return "UNKNOWN";
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(typeAsString())
+                .append(": length=")
+                .append(Integer.toString(length()))
+                .append(", streamid=")
+                .append(streamid)
+                .append(", flags=");
+
+        int f = flags;
+        int i = 0;
+        if (f == 0) {
+            sb.append("0 ");
+        } else {
+            while (f != 0) {
+                if ((f & 1) == 1) {
+                    sb.append(flagAsString(1 << i))
+                      .append(' ');
+                }
+                f = f >> 1;
+                i++;
+            }
+        }
+        return sb.toString();
+    }
+
+    // Override
+    public String flagAsString(int f) {
+        return "unknown";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/MalformedFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,46 @@
+package jdk.incubator.http.internal.frame;
+
+public class MalformedFrame extends Http2Frame {
+
+    private int errorCode;
+    // if errorStream == 0 means Connection Error; RFC 7540 5.4.1
+    // if errorStream != 0 means Stream Error; RFC 7540 5.4.2
+    private int errorStream;
+    private String msg;
+
+    /**
+     * Creates Connection Error malformed frame
+     * @param errorCode - error code, as specified by RFC 7540
+     * @param msg - internal debug message
+     */
+    public MalformedFrame(int errorCode, String msg) {
+        this(errorCode, 0 , msg);
+    }
+
+    /**
+     * Creates Stream Error malformed frame
+     * @param errorCode - error code, as specified by RFC 7540
+     * @param errorStream - id of error stream (RST_FRAME will be send for this stream)
+     * @param msg - internal debug message
+     */
+    public MalformedFrame(int errorCode, int errorStream, String msg) {
+        super(0, 0);
+        this.errorCode = errorCode;
+        this.errorStream = errorStream;
+        this.msg = msg;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " MalformedFrame, Error: " + ErrorFrame.stringForCode(errorCode)
+                + " streamid: " + streamid + " reason: " + msg;
+    }
+
+    public int getErrorCode() {
+        return errorCode;
+    }
+
+    public String getMessage() {
+        return msg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/OutgoingHeaders.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.HttpHeaders;
+
+/**
+ * Contains all parameters for outgoing headers. Is converted to
+ * HeadersFrame and ContinuationFrames by Http2Connection.
+ */
+public class OutgoingHeaders<T> extends Http2Frame {
+
+    int streamDependency;
+    int weight;
+    boolean exclusive;
+    T attachment;
+
+    public static final int PRIORITY = 0x20;
+
+    HttpHeaders user, system;
+
+    public OutgoingHeaders(HttpHeaders hdrs1, HttpHeaders hdrs2, T attachment) {
+        super(0, 0);
+        this.user = hdrs2;
+        this.system = hdrs1;
+        this.attachment = attachment;
+    }
+
+    public void setPriority(int streamDependency, boolean exclusive, int weight) {
+        this.streamDependency = streamDependency;
+        this.exclusive = exclusive;
+        this.weight = weight;
+        this.flags |= PRIORITY;
+    }
+
+    public int getStreamDependency() {
+        return streamDependency;
+    }
+
+    public int getWeight() {
+        return weight;
+    }
+
+    public boolean getExclusive() {
+        return exclusive;
+    }
+
+    public T getAttachment() {
+        return attachment;
+    }
+
+    public HttpHeaders getUserHeaders() {
+        return user;
+    }
+
+    public HttpHeaders getSystemHeaders() {
+        return system;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/PingFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+public class PingFrame extends Http2Frame {
+
+
+    private final byte[] data;
+
+    public static final int TYPE = 0x6;
+
+    // Flags
+    public static final int ACK = 0x1;
+
+    public PingFrame(int flags, byte[] data) {
+        super(0, flags);
+        assert data.length == 8;
+        this.data = data;
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return 8;
+    }
+
+    @Override
+    public String flagAsString(int flag) {
+        switch (flag) {
+        case ACK:
+            return "ACK";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public byte[] getData() {
+        return data;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/PriorityFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+public class PriorityFrame extends Http2Frame {
+
+    private final int streamDependency;
+    private final int weight;
+    private final boolean exclusive;
+
+    public static final int TYPE = 0x2;
+
+    public PriorityFrame(int streamId, int streamDependency, boolean exclusive, int weight) {
+        super(streamId, 0);
+        this.streamDependency = streamDependency;
+        this.exclusive = exclusive;
+        this.weight = weight;
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return 5;
+    }
+
+    public int streamDependency() {
+        return streamDependency;
+    }
+
+    public int weight() {
+        return weight;
+    }
+
+    public boolean exclusive() {
+        return exclusive;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/PushPromiseFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Utils;
+
+public class PushPromiseFrame extends HeaderFrame {
+
+    private int padLength;
+    private final int promisedStream;
+
+    public static final int TYPE = 0x5;
+
+    // Flags
+    public static final int END_HEADERS = 0x4;
+    public static final int PADDED = 0x8;
+
+    public PushPromiseFrame(int streamid, int flags, int promisedStream, ByteBufferReference[] buffers, int padLength) {
+        super(streamid, flags, buffers);
+        this.promisedStream = promisedStream;
+        if(padLength > 0 ) {
+            setPadLength(padLength);
+        }
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return headerLength + ((flags & PADDED) != 0 ? 5 : 4);
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " promisedStreamid: " + promisedStream
+                + " headerLength: " + headerLength;
+    }
+
+    @Override
+    public String flagAsString(int flag) {
+        switch (flag) {
+            case PADDED:
+                return "PADDED";
+            case END_HEADERS:
+                return "END_HEADERS";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public void setPadLength(int padLength) {
+        this.padLength = padLength;
+        flags |= PADDED;
+    }
+
+    public int getPadLength() {
+        return padLength;
+    }
+
+    public int getPromisedStream() {
+        return promisedStream;
+    }
+
+    @Override
+    public boolean endHeaders() {
+        return getFlag(END_HEADERS);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/ResetFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+public class ResetFrame extends ErrorFrame {
+
+    public static final int TYPE = 0x3;
+
+    // See ErrorFrame for error values
+
+    public ResetFrame(int streamid, int errorCode) {
+        super(streamid, 0, errorCode);
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return 4;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/SettingsFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class SettingsFrame extends Http2Frame {
+
+    private final int[] parameters;
+
+    public static final int TYPE = 0x4;
+
+    // Flags
+    public static final int ACK = 0x1;
+
+    @Override
+    public String flagAsString(int flag) {
+        switch (flag) {
+        case ACK:
+            return "ACK";
+        }
+        return super.flagAsString(flag);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(super.toString())
+          .append(" Settings: ");
+
+        for (int i = 0; i < MAX_PARAM; i++) {
+            if (parameters[i] != -1) {
+                sb.append(name(i))
+                  .append("=")
+                  .append(Integer.toString(parameters[i]))
+                  .append(' ');
+            }
+        }
+        return sb.toString();
+    }
+
+    // Parameters
+    public static final int HEADER_TABLE_SIZE = 0x1;
+    public static final int ENABLE_PUSH = 0x2;
+    public static final int MAX_CONCURRENT_STREAMS = 0x3;
+    public static final int INITIAL_WINDOW_SIZE = 0x4;
+    public static final int MAX_FRAME_SIZE = 0x5;
+    public static final int MAX_HEADER_LIST_SIZE = 0x6;
+
+    private String name(int i) {
+        switch (i+1) {
+        case HEADER_TABLE_SIZE:
+            return "HEADER_TABLE_SIZE";
+        case ENABLE_PUSH:
+            return "ENABLE_PUSH";
+        case MAX_CONCURRENT_STREAMS:
+            return "MAX_CONCURRENT_STREAMS";
+        case INITIAL_WINDOW_SIZE:
+            return "INITIAL_WINDOW_SIZE";
+        case MAX_FRAME_SIZE:
+            return "MAX_FRAME_SIZE";
+        case MAX_HEADER_LIST_SIZE:
+            return "MAX_HEADER_LIST_SIZE";
+        }
+        return "unknown parameter";
+    }
+    public static final int MAX_PARAM = 0x6;
+
+    public SettingsFrame(int flags) {
+        super(0, flags);
+        parameters = new int [MAX_PARAM];
+        Arrays.fill(parameters, -1);
+    }
+
+    public SettingsFrame() {
+        this(0);
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    public int getParameter(int paramID) {
+        if (paramID > MAX_PARAM) {
+            throw new IllegalArgumentException("illegal parameter");
+        }
+        return parameters[paramID-1];
+    }
+
+    public SettingsFrame setParameter(int paramID, int value) {
+        if (paramID > MAX_PARAM) {
+            throw new IllegalArgumentException("illegal parameter");
+        }
+        parameters[paramID-1] = value;
+        return this;
+    }
+
+    int length() {
+        int len = 0;
+        for (int i : parameters) {
+            if (i != -1) {
+                len  += 6;
+            }
+        }
+        return len;
+    }
+
+    void toByteBuffer(ByteBuffer buf) {
+        for (int i = 0; i < MAX_PARAM; i++) {
+            if (parameters[i] != -1) {
+                buf.putShort((short) (i + 1));
+                buf.putInt(parameters[i]);
+            }
+        }
+    }
+
+    public byte[] toByteArray() {
+        byte[] bytes = new byte[length()];
+        ByteBuffer buf = ByteBuffer.wrap(bytes);
+        toByteBuffer(buf);
+        return bytes;
+    }
+
+    private static final int K = 1024;
+
+    public static SettingsFrame getDefaultSettings() {
+        SettingsFrame f = new SettingsFrame();
+        // TODO: check these values
+        f.setParameter(ENABLE_PUSH, 1);
+        f.setParameter(HEADER_TABLE_SIZE, 4 * K);
+        f.setParameter(MAX_CONCURRENT_STREAMS, 35);
+        f.setParameter(INITIAL_WINDOW_SIZE, 64 * K - 1);
+        f.setParameter(MAX_FRAME_SIZE, 16 * K);
+        return f;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/WindowUpdateFrame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.frame;
+
+public class WindowUpdateFrame extends Http2Frame {
+
+    private final int windowUpdate;
+
+    public static final int TYPE = 0x8;
+
+    public WindowUpdateFrame(int streamid, int windowUpdate) {
+        super(streamid, 0);
+        this.windowUpdate = windowUpdate;
+    }
+
+    @Override
+    public int type() {
+        return TYPE;
+    }
+
+    @Override
+    int length() {
+        return 4;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(super.toString())
+          .append(" WindowUpdate: ")
+          .append(windowUpdate);
+        return sb.toString();
+    }
+
+    public int getUpdate() {
+        return this.windowUpdate;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/BinaryRepresentationWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+
+interface BinaryRepresentationWriter {
+
+    boolean write(HeaderTable table, ByteBuffer destination);
+
+    BinaryRepresentationWriter reset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/BulkSizeUpdateWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+
+import static java.util.Objects.requireNonNull;
+
+final class BulkSizeUpdateWriter implements BinaryRepresentationWriter {
+
+    private final SizeUpdateWriter writer = new SizeUpdateWriter();
+    private Iterator<Integer> maxSizes;
+    private boolean writing;
+    private boolean configured;
+
+    BulkSizeUpdateWriter maxHeaderTableSizes(Iterable<Integer> sizes) {
+        if (configured) {
+            throw new IllegalStateException("Already configured");
+        }
+        requireNonNull(sizes, "sizes");
+        maxSizes = sizes.iterator();
+        configured = true;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!configured) {
+            throw new IllegalStateException("Configure first");
+        }
+        while (true) {
+            if (writing) {
+                if (!writer.write(table, destination)) {
+                    return false;
+                }
+                writing = false;
+            } else if (maxSizes.hasNext()) {
+                writing = true;
+                writer.reset();
+                writer.maxHeaderTableSize(maxSizes.next());
+            } else {
+                configured = false;
+                return true;
+            }
+        }
+    }
+
+    @Override
+    public BulkSizeUpdateWriter reset() {
+        maxSizes = null;
+        writing = false;
+        configured = false;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/Decoder.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Decodes headers from their binary representation.
+ *
+ * <p>Typical lifecycle looks like this:
+ *
+ * <p> {@link #Decoder(int) new Decoder}
+ * ({@link #setMaxCapacity(int) setMaxCapacity}?
+ * {@link #decode(ByteBuffer, boolean, DecodingCallback) decode})*
+ *
+ * @apiNote
+ *
+ * <p> The design intentions behind Decoder were to facilitate flexible and
+ * incremental style of processing.
+ *
+ * <p> {@code Decoder} does not require a complete header block in a single
+ * {@code ByteBuffer}. The header block can be spread across many buffers of any
+ * size and decoded one-by-one the way it makes most sense for the user. This
+ * way also allows not to limit the size of the header block.
+ *
+ * <p> Headers are delivered to the {@linkplain DecodingCallback callback} as
+ * soon as they become decoded. Using the callback also gives the user a freedom
+ * to decide how headers are processed. The callback does not limit the number
+ * of headers decoded during single decoding operation.
+ *
+ * @since 9
+ */
+public final class Decoder {
+
+    private static final State[] states = new State[256];
+
+    static {
+        // To be able to do a quick lookup, each of 256 possibilities are mapped
+        // to corresponding states.
+        //
+        // We can safely do this since patterns 1, 01, 001, 0001, 0000 are
+        // Huffman prefixes and therefore are inherently not ambiguous.
+        //
+        // I do it mainly for better debugging (to not go each time step by step
+        // through if...else tree). As for performance win for the decoding, I
+        // believe is negligible.
+        for (int i = 0; i < states.length; i++) {
+            if ((i & 0b1000_0000) == 0b1000_0000) {
+                states[i] = State.INDEXED;
+            } else if ((i & 0b1100_0000) == 0b0100_0000) {
+                states[i] = State.LITERAL_WITH_INDEXING;
+            } else if ((i & 0b1110_0000) == 0b0010_0000) {
+                states[i] = State.SIZE_UPDATE;
+            } else if ((i & 0b1111_0000) == 0b0001_0000) {
+                states[i] = State.LITERAL_NEVER_INDEXED;
+            } else if ((i & 0b1111_0000) == 0b0000_0000) {
+                states[i] = State.LITERAL;
+            } else {
+                throw new InternalError(String.valueOf(i));
+            }
+        }
+    }
+
+    private final HeaderTable table;
+
+    private State state = State.READY;
+    private final IntegerReader integerReader;
+    private final StringReader stringReader;
+    private final StringBuilder name;
+    private final StringBuilder value;
+    private int intValue;
+    private boolean firstValueRead;
+    private boolean firstValueIndex;
+    private boolean nameHuffmanEncoded;
+    private boolean valueHuffmanEncoded;
+    private int capacity;
+
+    /**
+     * Constructs a {@code Decoder} with the specified initial capacity of the
+     * header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     */
+    public Decoder(int capacity) {
+        setMaxCapacity(capacity);
+        table = new HeaderTable(capacity);
+        integerReader = new IntegerReader();
+        stringReader = new StringReader();
+        name = new StringBuilder(512);
+        value = new StringBuilder(1024);
+    }
+
+    /**
+     * Sets a maximum capacity of the header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     */
+    public void setMaxCapacity(int capacity) {
+        if (capacity < 0) {
+            throw new IllegalArgumentException("capacity >= 0: " + capacity);
+        }
+        // FIXME: await capacity update if less than what was prior to it
+        this.capacity = capacity;
+    }
+
+    /**
+     * Decodes a header block from the given buffer to the given callback.
+     *
+     * <p> Suppose a header block is represented by a sequence of {@code
+     * ByteBuffer}s in the form of {@code Iterator<ByteBuffer>}. And the
+     * consumer of decoded headers is represented by the callback. Then to
+     * decode the header block, the following approach might be used:
+     *
+     * <pre>{@code
+     * while (buffers.hasNext()) {
+     *     ByteBuffer input = buffers.next();
+     *     decoder.decode(input, callback, !buffers.hasNext());
+     * }
+     * }</pre>
+     *
+     * <p> The decoder reads as much as possible of the header block from the
+     * given buffer, starting at the buffer's position, and increments its
+     * position to reflect the bytes read. The buffer's mark and limit will not
+     * be modified.
+     *
+     * <p> Once the method is invoked with {@code endOfHeaderBlock == true}, the
+     * current header block is deemed ended, and inconsistencies, if any, are
+     * reported immediately by throwing an {@code UncheckedIOException}.
+     *
+     * <p> Each callback method is called only after the implementation has
+     * processed the corresponding bytes. If the bytes revealed a decoding
+     * error, the callback method is not called.
+     *
+     * <p> In addition to exceptions thrown directly by the method, any
+     * exceptions thrown from the {@code callback} will bubble up.
+     *
+     * @apiNote The method asks for {@code endOfHeaderBlock} flag instead of
+     * returning it for two reasons. The first one is that the user of the
+     * decoder always knows which chunk is the last. The second one is to throw
+     * the most detailed exception possible, which might be useful for
+     * diagnosing issues.
+     *
+     * @implNote This implementation is not atomic in respect to decoding
+     * errors. In other words, if the decoding operation has thrown a decoding
+     * error, the decoder is no longer usable.
+     *
+     * @param headerBlock
+     *         the chunk of the header block, may be empty
+     * @param endOfHeaderBlock
+     *         true if the chunk is the final (or the only one) in the sequence
+     *
+     * @param consumer
+     *         the callback
+     * @throws UncheckedIOException
+     *         in case of a decoding error
+     * @throws NullPointerException
+     *         if either headerBlock or consumer are null
+     */
+    public void decode(ByteBuffer headerBlock, boolean endOfHeaderBlock,
+                       DecodingCallback consumer) {
+        requireNonNull(headerBlock, "headerBlock");
+        requireNonNull(consumer, "consumer");
+        while (headerBlock.hasRemaining()) {
+            proceed(headerBlock, consumer);
+        }
+        if (endOfHeaderBlock && state != State.READY) {
+            throw new UncheckedIOException(
+                    new ProtocolException("Unexpected end of header block"));
+        }
+    }
+
+    private void proceed(ByteBuffer input, DecodingCallback action) {
+        switch (state) {
+            case READY:
+                resumeReady(input);
+                break;
+            case INDEXED:
+                resumeIndexed(input, action);
+                break;
+            case LITERAL:
+                resumeLiteral(input, action);
+                break;
+            case LITERAL_WITH_INDEXING:
+                resumeLiteralWithIndexing(input, action);
+                break;
+            case LITERAL_NEVER_INDEXED:
+                resumeLiteralNeverIndexed(input, action);
+                break;
+            case SIZE_UPDATE:
+                resumeSizeUpdate(input, action);
+                break;
+            default:
+                throw new InternalError(
+                        "Unexpected decoder state: " + String.valueOf(state));
+        }
+    }
+
+    private void resumeReady(ByteBuffer input) {
+        int b = input.get(input.position()) & 0xff; // absolute read
+        State s = states[b];
+        switch (s) {
+            case INDEXED:
+                integerReader.configure(7);
+                state = State.INDEXED;
+                firstValueIndex = true;
+                break;
+            case LITERAL:
+                state = State.LITERAL;
+                firstValueIndex = (b & 0b0000_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(4);
+                }
+                break;
+            case LITERAL_WITH_INDEXING:
+                state = State.LITERAL_WITH_INDEXING;
+                firstValueIndex = (b & 0b0011_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(6);
+                }
+                break;
+            case LITERAL_NEVER_INDEXED:
+                state = State.LITERAL_NEVER_INDEXED;
+                firstValueIndex = (b & 0b0000_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(4);
+                }
+                break;
+            case SIZE_UPDATE:
+                integerReader.configure(5);
+                state = State.SIZE_UPDATE;
+                firstValueIndex = true;
+                break;
+            default:
+                throw new InternalError(String.valueOf(s));
+        }
+        if (!firstValueIndex) {
+            input.get(); // advance, next stop: "String Literal"
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 1 |        Index (7+)         |
+    //            +---+---------------------------+
+    //
+    private void resumeIndexed(ByteBuffer input, DecodingCallback action) {
+        if (!integerReader.read(input)) {
+            return;
+        }
+        intValue = integerReader.get();
+        integerReader.reset();
+        try {
+            HeaderTable.HeaderField f = table.get(intValue);
+            action.onIndexed(intValue, f.name, f.value);
+        } finally {
+            state = State.READY;
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 0 |  Index (4+)   |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 0 |       0       |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteral(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                action.onLiteral(intValue, f.name, value, valueHuffmanEncoded);
+            } else {
+                action.onLiteral(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
+            }
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 1 |      Index (6+)       |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 1 |           0           |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteralWithIndexing(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            //
+            // 1. (name, value) will be stored in the table as strings
+            // 2. Most likely the callback will also create strings from them
+            // ------------------------------------------------------------------------
+            //    Let's create those string beforehand (and only once!) to benefit everyone
+            //
+            String n;
+            String v = value.toString();
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                n = f.name;
+                action.onLiteralWithIndexing(intValue, n, v, valueHuffmanEncoded);
+            } else {
+                n = name.toString();
+                action.onLiteralWithIndexing(n, nameHuffmanEncoded, v, valueHuffmanEncoded);
+            }
+            table.put(n, v);
+        } catch (IllegalArgumentException | IllegalStateException e) {
+            throw new UncheckedIOException(
+                    (IOException) new ProtocolException().initCause(e));
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 1 |  Index (4+)   |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 1 |       0       |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteralNeverIndexed(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                action.onLiteralNeverIndexed(intValue, f.name, value, valueHuffmanEncoded);
+            } else {
+                action.onLiteralNeverIndexed(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
+            }
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 1 |   Max size (5+)   |
+    //            +---+---------------------------+
+    //
+    private void resumeSizeUpdate(ByteBuffer input, DecodingCallback action) {
+        if (!integerReader.read(input)) {
+            return;
+        }
+        intValue = integerReader.get();
+        assert intValue >= 0;
+        if (intValue > capacity) {
+            throw new UncheckedIOException(new ProtocolException(
+                    format("Received capacity exceeds expected: " +
+                            "capacity=%s, expected=%s", intValue, capacity)));
+        }
+        integerReader.reset();
+        try {
+            action.onSizeUpdate(intValue);
+            table.setMaxSize(intValue);
+        } finally {
+            state = State.READY;
+        }
+    }
+
+    private boolean completeReading(ByteBuffer input) {
+        if (!firstValueRead) {
+            if (firstValueIndex) {
+                if (!integerReader.read(input)) {
+                    return false;
+                }
+                intValue = integerReader.get();
+                integerReader.reset();
+            } else {
+                if (!stringReader.read(input, name)) {
+                    return false;
+                }
+                nameHuffmanEncoded = stringReader.isHuffmanEncoded();
+                stringReader.reset();
+            }
+            firstValueRead = true;
+            return false;
+        } else {
+            if (!stringReader.read(input, value)) {
+                return false;
+            }
+        }
+        valueHuffmanEncoded = stringReader.isHuffmanEncoded();
+        stringReader.reset();
+        return true;
+    }
+
+    private void cleanUpAfterReading() {
+        name.setLength(0);
+        value.setLength(0);
+        firstValueRead = false;
+        state = State.READY;
+    }
+
+    private enum State {
+        READY,
+        INDEXED,
+        LITERAL_NEVER_INDEXED,
+        LITERAL,
+        LITERAL_WITH_INDEXING,
+        SIZE_UPDATE
+    }
+
+    HeaderTable getTable() {
+        return table;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/DecodingCallback.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Delivers results of the {@link Decoder#decode(ByteBuffer, boolean,
+ * DecodingCallback) decoding operation}.
+ *
+ * <p> Methods of the callback are never called by a decoder with any of the
+ * arguments being {@code null}.
+ *
+ * @apiNote
+ *
+ * <p> The callback provides methods for all possible <a
+ * href="https://tools.ietf.org/html/rfc7541#section-6">binary
+ * representations</a>. This could be useful for implementing an intermediary,
+ * logging, debugging, etc.
+ *
+ * <p> The callback is an interface in order to interoperate with lambdas (in
+ * the most common use case):
+ * <pre>{@code
+ *     DecodingCallback callback = (name, value) -> System.out.println(name + ", " + value);
+ * }</pre>
+ *
+ * <p> Names and values are {@link CharSequence}s rather than {@link String}s in
+ * order to allow users to decide whether or not they need to create objects. A
+ * {@code CharSequence} might be used in-place, for example, to be appended to
+ * an {@link Appendable} (e.g. {@link StringBuilder}) and then discarded.
+ *
+ * <p> That said, if a passed {@code CharSequence} needs to outlast the method
+ * call, it needs to be copied.
+ *
+ * @since 9
+ */
+@FunctionalInterface
+public interface DecodingCallback {
+
+    /**
+     * A method the more specific methods of the callback forward their calls
+     * to.
+     *
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     */
+    void onDecoded(CharSequence name, CharSequence value);
+
+    /**
+     * A more finer-grained version of {@link #onDecoded(CharSequence,
+     * CharSequence)} that also reports on value sensitivity.
+     *
+     * <p> Value sensitivity must be considered, for example, when implementing
+     * an intermediary. A {@code value} is sensitive if it was represented as <a
+     * href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal Header
+     * Field Never Indexed</a>.
+     *
+     * <p> It is required that intermediaries MUST use the {@linkplain
+     * Encoder#header(CharSequence, CharSequence, boolean) same representation}
+     * for encoding this header field in order to protect its value which is not
+     * to be put at risk by compressing it.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes {@code onDecoded(name, value)}.
+     *
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param sensitive
+     *         whether or not the value is sensitive
+     *
+     * @see #onLiteralNeverIndexed(int, CharSequence, CharSequence, boolean)
+     * @see #onLiteralNeverIndexed(CharSequence, boolean, CharSequence, boolean)
+     */
+    default void onDecoded(CharSequence name, CharSequence value,
+                           boolean sensitive) {
+        onDecoded(name, value);
+    }
+
+    /**
+     * An <a href="https://tools.ietf.org/html/rfc7541#section-6.1">Indexed
+     * Header Field</a> decoded.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     */
+    default void onIndexed(int index, CharSequence name, CharSequence value) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
+     * Header Field without Indexing</a> decoded, where a {@code name} was
+     * referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteral(int index, CharSequence name,
+                           CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
+     * Header Field without Indexing</a> decoded, where both a {@code name} and
+     * a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteral(CharSequence name, boolean nameHuffman,
+                           CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
+     * Header Field Never Indexed</a> decoded, where a {@code name}
+     * was referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, true)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralNeverIndexed(int index, CharSequence name,
+                                       CharSequence value,
+                                       boolean valueHuffman) {
+        onDecoded(name, value, true);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
+     * Header Field Never Indexed</a> decoded, where both a {@code
+     * name} and a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, true)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralNeverIndexed(CharSequence name, boolean nameHuffman,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, true);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
+     * Header Field with Incremental Indexing</a> decoded, where a {@code name}
+     * was referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralWithIndexing(int index,
+                                       CharSequence name,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
+     * Header Field with Incremental Indexing</a> decoded, where both a {@code
+     * name} and a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralWithIndexing(CharSequence name, boolean nameHuffman,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.3">Dynamic Table
+     * Size Update</a> decoded.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation does nothing.
+     *
+     * @param capacity
+     *         new capacity of the header table
+     */
+    default void onSizeUpdate(int capacity) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/Encoder.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Encodes headers to their binary representation.
+ *
+ * <p>Typical lifecycle looks like this:
+ *
+ * <p> {@link #Encoder(int) new Encoder}
+ * ({@link #setMaxCapacity(int) setMaxCapacity}?
+ * {@link #encode(ByteBuffer) encode})*
+ *
+ * <p> Suppose headers are represented by {@code Map<String, List<String>>}. A
+ * supplier and a consumer of {@link ByteBuffer}s in forms of {@code
+ * Supplier<ByteBuffer>} and {@code Consumer<ByteBuffer>} respectively. Then to
+ * encode headers, the following approach might be used:
+ *
+ * <pre>{@code
+ *     for (Map.Entry<String, List<String>> h : headers.entrySet()) {
+ *         String name = h.getKey();
+ *         for (String value : h.getValue()) {
+ *             encoder.header(name, value);        // Set up header
+ *             boolean encoded;
+ *             do {
+ *                 ByteBuffer b = buffersSupplier.get();
+ *                 encoded = encoder.encode(b);    // Encode the header
+ *                 buffersConsumer.accept(b);
+ *             } while (!encoded);
+ *         }
+ *     }
+ * }</pre>
+ *
+ * <p> Though the specification <a
+ * href="https://tools.ietf.org/html/rfc7541#section-2"> does not define</a> how
+ * an encoder is to be implemented, a default implementation is provided by the
+ * method {@link #header(CharSequence, CharSequence, boolean)}.
+ *
+ * <p> To provide a custom encoding implementation, {@code Encoder} has to be
+ * extended. A subclass then can access methods for encoding using specific
+ * representations (e.g. {@link #literal(int, CharSequence, boolean) literal},
+ * {@link #indexed(int) indexed}, etc.)
+ *
+ * @apiNote
+ *
+ * <p> An Encoder provides an incremental way of encoding headers.
+ * {@link #encode(ByteBuffer)} takes a buffer a returns a boolean indicating
+ * whether, or not, the buffer was sufficiently sized to hold the
+ * remaining of the encoded representation.
+ *
+ * <p> This way, there's no need to provide a buffer of a specific size, or to
+ * resize (and copy) the buffer on demand, when the remaining encoded
+ * representation will not fit in the buffer's remaining space. Instead, an
+ * array of existing buffers can be used, prepended with a frame that encloses
+ * the resulting header block afterwards.
+ *
+ * <p> Splitting the encoding operation into header set up and header encoding,
+ * separates long lived arguments ({@code name}, {@code value}, {@code
+ * sensitivity}, etc.) from the short lived ones (e.g. {@code buffer}),
+ * simplifying each operation itself.
+ *
+ * @implNote
+ *
+ * <p> The default implementation does not use dynamic table. It reports to a
+ * coupled Decoder a size update with the value of {@code 0}, and never changes
+ * it afterwards.
+ *
+ * @since 9
+ */
+public class Encoder {
+
+    // TODO: enum: no huffman/smart huffman/always huffman
+    private static final boolean DEFAULT_HUFFMAN = true;
+
+    private final IndexedWriter indexedWriter = new IndexedWriter();
+    private final LiteralWriter literalWriter = new LiteralWriter();
+    private final LiteralNeverIndexedWriter literalNeverIndexedWriter
+            = new LiteralNeverIndexedWriter();
+    private final LiteralWithIndexingWriter literalWithIndexingWriter
+            = new LiteralWithIndexingWriter();
+    private final SizeUpdateWriter sizeUpdateWriter = new SizeUpdateWriter();
+    private final BulkSizeUpdateWriter bulkSizeUpdateWriter
+            = new BulkSizeUpdateWriter();
+
+    private BinaryRepresentationWriter writer;
+    private final HeaderTable headerTable;
+
+    private boolean encoding;
+
+    private int maxCapacity;
+    private int currCapacity;
+    private int lastCapacity;
+    private long minCapacity;
+    private boolean capacityUpdate;
+    private boolean configuredCapacityUpdate;
+
+    /**
+     * Constructs an {@code Encoder} with the specified maximum capacity of the
+     * header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param maxCapacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if maxCapacity is negative
+     */
+    public Encoder(int maxCapacity) {
+        if (maxCapacity < 0) {
+            throw new IllegalArgumentException("maxCapacity >= 0: " + maxCapacity);
+        }
+        // Initial maximum capacity update mechanics
+        minCapacity = Long.MAX_VALUE;
+        currCapacity = -1;
+        setMaxCapacity(maxCapacity);
+        headerTable = new HeaderTable(lastCapacity);
+    }
+
+    /**
+     * Sets up the given header {@code (name, value)}.
+     *
+     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
+     *
+     * @param name
+     *         the name
+     * @param value
+     *         the value
+     *
+     * @throws NullPointerException
+     *         if any of the arguments are {@code null}
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     * @see #header(CharSequence, CharSequence, boolean)
+     */
+    public void header(CharSequence name, CharSequence value)
+            throws IllegalStateException {
+        header(name, value, false);
+    }
+
+    /**
+     * Sets up the given header {@code (name, value)} with possibly sensitive
+     * value.
+     *
+     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
+     *
+     * @param name
+     *         the name
+     * @param value
+     *         the value
+     * @param sensitive
+     *         whether or not the value is sensitive
+     *
+     * @throws NullPointerException
+     *         if any of the arguments are {@code null}
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     * @see #header(CharSequence, CharSequence)
+     * @see DecodingCallback#onDecoded(CharSequence, CharSequence, boolean)
+     */
+    public void header(CharSequence name, CharSequence value,
+                       boolean sensitive) throws IllegalStateException {
+        // Arguably a good balance between complexity of implementation and
+        // efficiency of encoding
+        requireNonNull(name, "name");
+        requireNonNull(value, "value");
+        HeaderTable t = getHeaderTable();
+        int index = t.indexOf(name, value);
+        if (index > 0) {
+            indexed(index);
+        } else if (index < 0) {
+            if (sensitive) {
+                literalNeverIndexed(-index, value, DEFAULT_HUFFMAN);
+            } else {
+                literal(-index, value, DEFAULT_HUFFMAN);
+            }
+        } else {
+            if (sensitive) {
+                literalNeverIndexed(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
+            } else {
+                literal(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
+            }
+        }
+    }
+
+    /**
+     * Sets a maximum capacity of the header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * <p> May be called any number of times after or before a complete header
+     * has been encoded.
+     *
+     * <p> If the encoder decides to change the actual capacity, an update will
+     * be encoded before a new encoding operation starts.
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     */
+    public void setMaxCapacity(int capacity) {
+        checkEncoding();
+        if (capacity < 0) {
+            throw new IllegalArgumentException("capacity >= 0: " + capacity);
+        }
+        int calculated = calculateCapacity(capacity);
+        if (calculated < 0 || calculated > capacity) {
+            throw new IllegalArgumentException(
+                    format("0 <= calculated <= capacity: calculated=%s, capacity=%s",
+                            calculated, capacity));
+        }
+        capacityUpdate = true;
+        // maxCapacity needs to be updated unconditionally, so the encoder
+        // always has the newest one (in case it decides to update it later
+        // unsolicitedly)
+        // Suppose maxCapacity = 4096, and the encoder has decided to use only
+        // 2048. It later can choose anything else from the region [0, 4096].
+        maxCapacity = capacity;
+        lastCapacity = calculated;
+        minCapacity = Math.min(minCapacity, lastCapacity);
+    }
+
+    protected int calculateCapacity(int maxCapacity) {
+        // Default implementation of the Encoder won't add anything to the
+        // table, therefore no need for a table space
+        return 0;
+    }
+
+    /**
+     * Encodes the {@linkplain #header(CharSequence, CharSequence) set up}
+     * header into the given buffer.
+     *
+     * <p> The encoder writes as much as possible of the header's binary
+     * representation into the given buffer, starting at the buffer's position,
+     * and increments its position to reflect the bytes written. The buffer's
+     * mark and limit will not be modified.
+     *
+     * <p> Once the method has returned {@code true}, the current header is
+     * deemed encoded. A new header may be set up.
+     *
+     * @param headerBlock
+     *         the buffer to encode the header into, may be empty
+     *
+     * @return {@code true} if the current header has been fully encoded,
+     *         {@code false} otherwise
+     *
+     * @throws NullPointerException
+     *         if the buffer is {@code null}
+     * @throws ReadOnlyBufferException
+     *         if this buffer is read-only
+     * @throws IllegalStateException
+     *         if there is no set up header
+     */
+    public final boolean encode(ByteBuffer headerBlock) {
+        if (!encoding) {
+            throw new IllegalStateException("A header hasn't been set up");
+        }
+        if (!prependWithCapacityUpdate(headerBlock)) {
+            return false;
+        }
+        boolean done = writer.write(headerTable, headerBlock);
+        if (done) {
+            writer.reset(); // FIXME: WHY?
+            encoding = false;
+        }
+        return done;
+    }
+
+    private boolean prependWithCapacityUpdate(ByteBuffer headerBlock) {
+        if (capacityUpdate) {
+            if (!configuredCapacityUpdate) {
+                List<Integer> sizes = new LinkedList<>();
+                if (minCapacity < currCapacity) {
+                    sizes.add((int) minCapacity);
+                    if (minCapacity != lastCapacity) {
+                        sizes.add(lastCapacity);
+                    }
+                } else if (lastCapacity != currCapacity) {
+                    sizes.add(lastCapacity);
+                }
+                bulkSizeUpdateWriter.maxHeaderTableSizes(sizes);
+                configuredCapacityUpdate = true;
+            }
+            boolean done = bulkSizeUpdateWriter.write(headerTable, headerBlock);
+            if (done) {
+                minCapacity = lastCapacity;
+                currCapacity = lastCapacity;
+                bulkSizeUpdateWriter.reset();
+                capacityUpdate = false;
+                configuredCapacityUpdate = false;
+            }
+            return done;
+        }
+        return true;
+    }
+
+    protected final void indexed(int index) throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = indexedWriter.index(index);
+    }
+
+    protected final void literal(int index, CharSequence value,
+                                 boolean useHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalWriter
+                .index(index).value(value, useHuffman);
+    }
+
+    protected final void literal(CharSequence name, boolean nameHuffman,
+                                 CharSequence value, boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void literalNeverIndexed(int index,
+                                             CharSequence value,
+                                             boolean valueHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalNeverIndexedWriter
+                .index(index).value(value, valueHuffman);
+    }
+
+    protected final void literalNeverIndexed(CharSequence name,
+                                             boolean nameHuffman,
+                                             CharSequence value,
+                                             boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalNeverIndexedWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void literalWithIndexing(int index,
+                                             CharSequence value,
+                                             boolean valueHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalWithIndexingWriter
+                .index(index).value(value, valueHuffman);
+    }
+
+    protected final void literalWithIndexing(CharSequence name,
+                                             boolean nameHuffman,
+                                             CharSequence value,
+                                             boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalWithIndexingWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void sizeUpdate(int capacity)
+            throws IllegalArgumentException {
+        checkEncoding();
+        // Ensure subclass follows the contract
+        if (capacity > this.maxCapacity) {
+            throw new IllegalArgumentException(
+                    format("capacity <= maxCapacity: capacity=%s, maxCapacity=%s",
+                            capacity, maxCapacity));
+        }
+        writer = sizeUpdateWriter.maxHeaderTableSize(capacity);
+    }
+
+    protected final int getMaxCapacity() {
+        return maxCapacity;
+    }
+
+    protected final HeaderTable getHeaderTable() {
+        return headerTable;
+    }
+
+    protected final void checkEncoding() {
+        if (encoding) {
+            throw new IllegalStateException(
+                    "Previous encoding operation hasn't finished yet");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/HeaderTable.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import static java.lang.String.format;
+
+//
+// Header Table combined from two tables: static and dynamic.
+//
+// There is a single address space for index values. Index-aware methods
+// correspond to the table as a whole. Size-aware methods only to the dynamic
+// part of it.
+//
+final class HeaderTable {
+
+    private static final HeaderField[] staticTable = {
+            null, // To make index 1-based, instead of 0-based
+            new HeaderField(":authority"),
+            new HeaderField(":method", "GET"),
+            new HeaderField(":method", "POST"),
+            new HeaderField(":path", "/"),
+            new HeaderField(":path", "/index.html"),
+            new HeaderField(":scheme", "http"),
+            new HeaderField(":scheme", "https"),
+            new HeaderField(":status", "200"),
+            new HeaderField(":status", "204"),
+            new HeaderField(":status", "206"),
+            new HeaderField(":status", "304"),
+            new HeaderField(":status", "400"),
+            new HeaderField(":status", "404"),
+            new HeaderField(":status", "500"),
+            new HeaderField("accept-charset"),
+            new HeaderField("accept-encoding", "gzip, deflate"),
+            new HeaderField("accept-language"),
+            new HeaderField("accept-ranges"),
+            new HeaderField("accept"),
+            new HeaderField("access-control-allow-origin"),
+            new HeaderField("age"),
+            new HeaderField("allow"),
+            new HeaderField("authorization"),
+            new HeaderField("cache-control"),
+            new HeaderField("content-disposition"),
+            new HeaderField("content-encoding"),
+            new HeaderField("content-language"),
+            new HeaderField("content-length"),
+            new HeaderField("content-location"),
+            new HeaderField("content-range"),
+            new HeaderField("content-type"),
+            new HeaderField("cookie"),
+            new HeaderField("date"),
+            new HeaderField("etag"),
+            new HeaderField("expect"),
+            new HeaderField("expires"),
+            new HeaderField("from"),
+            new HeaderField("host"),
+            new HeaderField("if-match"),
+            new HeaderField("if-modified-since"),
+            new HeaderField("if-none-match"),
+            new HeaderField("if-range"),
+            new HeaderField("if-unmodified-since"),
+            new HeaderField("last-modified"),
+            new HeaderField("link"),
+            new HeaderField("location"),
+            new HeaderField("max-forwards"),
+            new HeaderField("proxy-authenticate"),
+            new HeaderField("proxy-authorization"),
+            new HeaderField("range"),
+            new HeaderField("referer"),
+            new HeaderField("refresh"),
+            new HeaderField("retry-after"),
+            new HeaderField("server"),
+            new HeaderField("set-cookie"),
+            new HeaderField("strict-transport-security"),
+            new HeaderField("transfer-encoding"),
+            new HeaderField("user-agent"),
+            new HeaderField("vary"),
+            new HeaderField("via"),
+            new HeaderField("www-authenticate")
+    };
+
+    private static final int STATIC_TABLE_LENGTH = staticTable.length - 1;
+    private static final int ENTRY_SIZE = 32;
+    private static final Map<String, LinkedHashMap<String, Integer>> staticIndexes;
+
+    static {
+        staticIndexes = new HashMap<>(STATIC_TABLE_LENGTH);
+        for (int i = 1; i <= STATIC_TABLE_LENGTH; i++) {
+            HeaderField f = staticTable[i];
+            Map<String, Integer> values = staticIndexes
+                    .computeIfAbsent(f.name, k -> new LinkedHashMap<>());
+            values.put(f.value, i);
+        }
+    }
+
+    private final Table dynamicTable = new Table(0);
+    private int maxSize;
+    private int size;
+
+    public HeaderTable(int maxSize) {
+        setMaxSize(maxSize);
+    }
+
+    //
+    // The method returns:
+    //
+    // * a positive integer i where i (i = [1..Integer.MAX_VALUE]) is an
+    // index of an entry with a header (n, v), where n.equals(name) &&
+    // v.equals(value)
+    //
+    // * a negative integer j where j (j = [-Integer.MAX_VALUE..-1]) is an
+    // index of an entry with a header (n, v), where n.equals(name)
+    //
+    // * 0 if there's no entry e such that e.getName().equals(name)
+    //
+    // The rationale behind this design is to allow to pack more useful data
+    // into a single invocation, facilitating a single pass where possible
+    // (the idea is the same as in java.util.Arrays.binarySearch(int[], int)).
+    //
+    public int indexOf(CharSequence name, CharSequence value) {
+        // Invoking toString() will possibly allocate Strings for the sake of
+        // the search, which doesn't feel right.
+        String n = name.toString();
+        String v = value.toString();
+
+        // 1. Try exact match in the static region
+        Map<String, Integer> values = staticIndexes.get(n);
+        if (values != null) {
+            Integer idx = values.get(v);
+            if (idx != null) {
+                return idx;
+            }
+        }
+        // 2. Try exact match in the dynamic region
+        int didx = dynamicTable.indexOf(n, v);
+        if (didx > 0) {
+            return STATIC_TABLE_LENGTH + didx;
+        } else if (didx < 0) {
+            if (values != null) {
+                // 3. Return name match from the static region
+                return -values.values().iterator().next(); // Iterator allocation
+            } else {
+                // 4. Return name match from the dynamic region
+                return -STATIC_TABLE_LENGTH + didx;
+            }
+        } else {
+            if (values != null) {
+                // 3. Return name match from the static region
+                return -values.values().iterator().next(); // Iterator allocation
+            } else {
+                return 0;
+            }
+        }
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public int maxSize() {
+        return maxSize;
+    }
+
+    public int length() {
+        return STATIC_TABLE_LENGTH + dynamicTable.size();
+    }
+
+    HeaderField get(int index) {
+        checkIndex(index);
+        if (index <= STATIC_TABLE_LENGTH) {
+            return staticTable[index];
+        } else {
+            return dynamicTable.get(index - STATIC_TABLE_LENGTH);
+        }
+    }
+
+    void put(CharSequence name, CharSequence value) {
+        // Invoking toString() will possibly allocate Strings. But that's
+        // unavoidable at this stage. If a CharSequence is going to be stored in
+        // the table, it must not be mutable (e.g. for the sake of hashing).
+        put(new HeaderField(name.toString(), value.toString()));
+    }
+
+    private void put(HeaderField h) {
+        int entrySize = sizeOf(h);
+        while (entrySize > maxSize - size && size != 0) {
+            evictEntry();
+        }
+        if (entrySize > maxSize - size) {
+            return;
+        }
+        size += entrySize;
+        dynamicTable.add(h);
+    }
+
+    void setMaxSize(int maxSize) {
+        if (maxSize < 0) {
+            throw new IllegalArgumentException
+                    ("maxSize >= 0: maxSize=" + maxSize);
+        }
+        while (maxSize < size && size != 0) {
+            evictEntry();
+        }
+        this.maxSize = maxSize;
+        int upperBound = (maxSize / ENTRY_SIZE) + 1;
+        this.dynamicTable.setCapacity(upperBound);
+    }
+
+    HeaderField evictEntry() {
+        HeaderField f = dynamicTable.remove();
+        size -= sizeOf(f);
+        return f;
+    }
+
+    @Override
+    public String toString() {
+        double used = maxSize == 0 ? 0 : 100 * (((double) size) / maxSize);
+        return format("entries: %d; used %s/%s (%.1f%%)", dynamicTable.size(),
+                size, maxSize, used);
+    }
+
+    int checkIndex(int index) {
+        if (index < 1 || index > STATIC_TABLE_LENGTH + dynamicTable.size()) {
+            throw new IllegalArgumentException(
+                    format("1 <= index <= length(): index=%s, length()=%s",
+                            index, length()));
+        }
+        return index;
+    }
+
+    int sizeOf(HeaderField f) {
+        return f.name.length() + f.value.length() + ENTRY_SIZE;
+    }
+
+    //
+    // Diagnostic information in the form used in the RFC 7541
+    //
+    String getStateString() {
+        if (size == 0) {
+            return "empty.";
+        }
+
+        StringBuilder b = new StringBuilder();
+        for (int i = 1, size = dynamicTable.size(); i <= size; i++) {
+            HeaderField e = dynamicTable.get(i);
+            b.append(format("[%3d] (s = %3d) %s: %s\n", i,
+                    sizeOf(e), e.name, e.value));
+        }
+        b.append(format("      Table size:%4s", this.size));
+        return b.toString();
+    }
+
+    // Convert to a Value Object (JDK-8046159)?
+    static final class HeaderField {
+
+        final String name;
+        final String value;
+
+        public HeaderField(String name) {
+            this(name, "");
+        }
+
+        public HeaderField(String name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return value.isEmpty() ? name : name + ": " + value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            HeaderField that = (HeaderField) o;
+            return name.equals(that.name) && value.equals(that.value);
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 * name.hashCode() + value.hashCode();
+        }
+    }
+
+    //
+    // To quickly find an index of an entry in the dynamic table with the given
+    // contents an effective inverse mapping is needed. Here's a simple idea
+    // behind such a mapping.
+    //
+    // # The problem:
+    //
+    // We have a queue with an O(1) lookup by index:
+    //
+    //     get: index -> x
+    //
+    // What we want is an O(1) reverse lookup:
+    //
+    //     indexOf: x -> index
+    //
+    // # Solution:
+    //
+    // Let's store an inverse mapping in a Map<x, Integer>. This have a problem
+    // that when a new element is added to the queue, all indexes in the map
+    // become invalid. Namely, the new element is assigned with an index of 1,
+    // and each index i, i > 1 becomes shifted by 1 to the left:
+    //
+    //     1, 1, 2, 3, ... , n-1, n
+    //
+    // Re-establishing the invariant would seem to require a pass through the
+    // map incrementing all indexes (map values) by 1, which is O(n).
+    //
+    // The good news is we can do much better then this!
+    //
+    // Let's create a single field of type long, called 'counter'. Then each
+    // time a new element 'x' is added to the queue, a value of this field gets
+    // incremented. Then the resulting value of the 'counter_x' is then put as a
+    // value under key 'x' to the map:
+    //
+    //    map.put(x, counter_x)
+    //
+    // It gives us a map that maps an element to a value the counter had at the
+    // time the element had been added.
+    //
+    // In order to retrieve an index of any element 'x' in the queue (at any
+    // given time) we simply need to subtract the value (the snapshot of the
+    // counter at the time when the 'x' was added) from the current value of the
+    // counter. This operation basically answers the question:
+    //
+    //     How many elements ago 'x' was the tail of the queue?
+    //
+    // Which is the same as its index in the queue now. Given, of course, it's
+    // still in the queue.
+    //
+    // I'm pretty sure in a real life long overflow will never happen, so it's
+    // not too practical to add recalibrating code, but a pedantic person might
+    // want to do so:
+    //
+    //     if (counter == Long.MAX_VALUE) {
+    //         recalibrate();
+    //     }
+    //
+    // Where 'recalibrate()' goes through the table doing this:
+    //
+    //     value -= counter
+    //
+    // That's given, of course, the size of the table itself is less than
+    // Long.MAX_VALUE :-)
+    //
+    private static final class Table {
+
+        private final Map<String, Map<String, Long>> map;
+        private final CircularBuffer<HeaderField> buffer;
+        private long counter = 1;
+
+        Table(int capacity) {
+            buffer = new CircularBuffer<>(capacity);
+            map = new HashMap<>(capacity);
+        }
+
+        void add(HeaderField f) {
+            buffer.add(f);
+            Map<String, Long> values = map.computeIfAbsent(f.name, k -> new HashMap<>());
+            values.put(f.value, counter++);
+        }
+
+        HeaderField get(int index) {
+            return buffer.get(index - 1);
+        }
+
+        int indexOf(String name, String value) {
+            Map<String, Long> values = map.get(name);
+            if (values == null) {
+                return 0;
+            }
+            Long index = values.get(value);
+            if (index != null) {
+                return (int) (counter - index);
+            } else {
+                assert !values.isEmpty();
+                Long any = values.values().iterator().next(); // Iterator allocation
+                return -(int) (counter - any);
+            }
+        }
+
+        HeaderField remove() {
+            HeaderField f = buffer.remove();
+            Map<String, Long> values = map.get(f.name);
+            Long index = values.remove(f.value);
+            assert index != null;
+            if (values.isEmpty()) {
+                map.remove(f.name);
+            }
+            return f;
+        }
+
+        int size() {
+            return buffer.size;
+        }
+
+        public void setCapacity(int capacity) {
+            buffer.resize(capacity);
+        }
+    }
+
+    //                    head
+    //                    v
+    // [ ][ ][A][B][C][D][ ][ ][ ]
+    //        ^
+    //        tail
+    //
+    //       |<- size ->| (4)
+    // |<------ capacity ------->| (9)
+    //
+    static final class CircularBuffer<E> {
+
+        int tail, head, size, capacity;
+        Object[] elements;
+
+        CircularBuffer(int capacity) {
+            this.capacity = capacity;
+            elements = new Object[capacity];
+        }
+
+        void add(E elem) {
+            if (size == capacity) {
+                throw new IllegalStateException(
+                        format("No room for '%s': capacity=%s", elem, capacity));
+            }
+            elements[head] = elem;
+            head = (head + 1) % capacity;
+            size++;
+        }
+
+        @SuppressWarnings("unchecked")
+        E remove() {
+            if (size == 0) {
+                throw new NoSuchElementException("Empty");
+            }
+            E elem = (E) elements[tail];
+            elements[tail] = null;
+            tail = (tail + 1) % capacity;
+            size--;
+            return elem;
+        }
+
+        @SuppressWarnings("unchecked")
+        E get(int index) {
+            if (index < 0 || index >= size) {
+                throw new IndexOutOfBoundsException(
+                        format("0 <= index <= capacity: index=%s, capacity=%s",
+                                index, capacity));
+            }
+            int idx = (tail + (size - index - 1)) % capacity;
+            return (E) elements[idx];
+        }
+
+        public void resize(int newCapacity) {
+            if (newCapacity < size) {
+                throw new IllegalStateException(
+                        format("newCapacity >= size: newCapacity=%s, size=%s",
+                                newCapacity, size));
+            }
+
+            Object[] newElements = new Object[newCapacity];
+
+            if (tail < head || size == 0) {
+                System.arraycopy(elements, tail, newElements, 0, size);
+            } else {
+                System.arraycopy(elements, tail, newElements, 0, elements.length - tail);
+                System.arraycopy(elements, 0, newElements, elements.length - tail, head);
+            }
+
+            elements = newElements;
+            tail = 0;
+            head = size;
+            this.capacity = newCapacity;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/Huffman.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
+import static java.lang.String.format;
+
+/**
+ * Huffman coding table.
+ *
+ * <p> Instances of this class are safe for use by multiple threads.
+ *
+ * @since 9
+ */
+public final class Huffman {
+
+    // TODO: check if reset is done in both reader and writer
+
+    static final class Reader {
+
+        private Node curr; // position in the trie
+        private int len;   // length of the path from the root to 'curr'
+        private int p;     // byte probe
+
+        {
+            reset();
+        }
+
+        public void read(ByteBuffer source, Appendable destination,
+                         boolean isLast) {
+            read(source, destination, true, isLast);
+        }
+
+        // Takes 'isLast' rather than returns whether the reading is done or
+        // not, for more informative exceptions.
+        void read(ByteBuffer source, Appendable destination, boolean reportEOS,
+                  boolean isLast) {
+
+            Node c = curr;
+            int l = len;
+            /*
+               Since ByteBuffer is itself stateful, its position is
+               remembered here NOT as a part of Reader's state,
+               but to set it back in the case of a failure
+             */
+            int pos = source.position();
+
+            while (source.hasRemaining()) {
+                int d = source.get();
+                for (; p != 0; p >>= 1) {
+                    c = c.getChild(p & d);
+                    l++;
+                    if (c.isLeaf()) {
+                        if (reportEOS && c.isEOSPath) {
+                            throw new IllegalArgumentException("Encountered EOS");
+                        }
+                        try {
+                            destination.append(c.getChar());
+                        } catch (RuntimeException | Error e) {
+                            source.position(pos);
+                            throw e;
+                        } catch (IOException e) {
+                            source.position(pos);
+                            throw new UncheckedIOException(e);
+                        }
+                        c = INSTANCE.root;
+                        l = 0;
+                    }
+                    curr = c;
+                    len = l;
+                }
+                resetProbe();
+                pos++;
+            }
+            if (!isLast) {
+                return; // it's too early to jump to any conclusions, let's wait
+            }
+            if (c.isLeaf()) {
+                return; // it's perfectly ok, no extra padding bits
+            }
+            if (c.isEOSPath && len <= 7) {
+                return; // it's ok, some extra padding bits
+            }
+            if (c.isEOSPath) {
+                throw new IllegalArgumentException(
+                        "Padding is too long (len=" + len + ") " +
+                                "or unexpected end of data");
+            }
+            throw new IllegalArgumentException(
+                    "Not a EOS prefix padding or unexpected end of data");
+        }
+
+        public void reset() {
+            curr = INSTANCE.root;
+            len = 0;
+            resetProbe();
+        }
+
+        private void resetProbe() {
+            p = 0x80;
+        }
+    }
+
+    static final class Writer {
+
+        private int pos;       // position in 'source'
+        private int avail = 8; // number of least significant bits available in 'curr'
+        private int curr;      // next byte to put to the destination
+        private int rem;       // number of least significant bits in 'code' yet to be processed
+        private int code;      // current code being written
+
+        private CharSequence source;
+        private int end;
+
+        public Writer from(CharSequence input, int start, int end) {
+            if (start < 0 || end < 0 || end > input.length() || start > end) {
+                throw new IndexOutOfBoundsException(
+                        String.format("input.length()=%s, start=%s, end=%s",
+                                input.length(), start, end));
+            }
+            pos = start;
+            this.end = end;
+            this.source = input;
+            return this;
+        }
+
+        public boolean write(ByteBuffer destination) {
+            for (; pos < end; pos++) {
+                if (rem == 0) {
+                    Code desc = INSTANCE.codeOf(source.charAt(pos));
+                    rem = desc.length;
+                    code = desc.code;
+                }
+                while (rem > 0) {
+                    if (rem < avail) {
+                        curr |= (code << (avail - rem));
+                        avail -= rem;
+                        rem = 0;
+                    } else {
+                        int c = (curr | (code >>> (rem - avail)));
+                        if (destination.hasRemaining()) {
+                            destination.put((byte) c);
+                        } else {
+                            return false;
+                        }
+                        curr = c;
+                        code <<= (32 - rem + avail);  // throw written bits off the cliff (is this Sparta?)
+                        code >>>= (32 - rem + avail); // return to the position
+                        rem -= avail;
+                        curr = 0;
+                        avail = 8;
+                    }
+                }
+            }
+
+            if (avail < 8) { // have to pad
+                if (destination.hasRemaining()) {
+                    destination.put((byte) (curr | (INSTANCE.EOS.code >>> (INSTANCE.EOS.length - avail))));
+                    avail = 8;
+                } else {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public Writer reset() {
+            source = null;
+            end = -1;
+            pos = -1;
+            avail = 8;
+            curr = 0;
+            code = 0;
+            return this;
+        }
+    }
+
+    /**
+     * Shared instance.
+     */
+    public static final Huffman INSTANCE = new Huffman();
+
+    private final Code EOS = new Code(0x3fffffff, 30);
+    private final Code[] codes = new Code[257];
+    private final Node root = new Node() {
+        @Override
+        public String toString() { return "root"; }
+    };
+
+    // TODO: consider builder and immutable trie
+    private Huffman() {
+        // @formatter:off
+        addChar(0,   0x1ff8,     13);
+        addChar(1,   0x7fffd8,   23);
+        addChar(2,   0xfffffe2,  28);
+        addChar(3,   0xfffffe3,  28);
+        addChar(4,   0xfffffe4,  28);
+        addChar(5,   0xfffffe5,  28);
+        addChar(6,   0xfffffe6,  28);
+        addChar(7,   0xfffffe7,  28);
+        addChar(8,   0xfffffe8,  28);
+        addChar(9,   0xffffea,   24);
+        addChar(10,  0x3ffffffc, 30);
+        addChar(11,  0xfffffe9,  28);
+        addChar(12,  0xfffffea,  28);
+        addChar(13,  0x3ffffffd, 30);
+        addChar(14,  0xfffffeb,  28);
+        addChar(15,  0xfffffec,  28);
+        addChar(16,  0xfffffed,  28);
+        addChar(17,  0xfffffee,  28);
+        addChar(18,  0xfffffef,  28);
+        addChar(19,  0xffffff0,  28);
+        addChar(20,  0xffffff1,  28);
+        addChar(21,  0xffffff2,  28);
+        addChar(22,  0x3ffffffe, 30);
+        addChar(23,  0xffffff3,  28);
+        addChar(24,  0xffffff4,  28);
+        addChar(25,  0xffffff5,  28);
+        addChar(26,  0xffffff6,  28);
+        addChar(27,  0xffffff7,  28);
+        addChar(28,  0xffffff8,  28);
+        addChar(29,  0xffffff9,  28);
+        addChar(30,  0xffffffa,  28);
+        addChar(31,  0xffffffb,  28);
+        addChar(32,  0x14,        6);
+        addChar(33,  0x3f8,      10);
+        addChar(34,  0x3f9,      10);
+        addChar(35,  0xffa,      12);
+        addChar(36,  0x1ff9,     13);
+        addChar(37,  0x15,        6);
+        addChar(38,  0xf8,        8);
+        addChar(39,  0x7fa,      11);
+        addChar(40,  0x3fa,      10);
+        addChar(41,  0x3fb,      10);
+        addChar(42,  0xf9,        8);
+        addChar(43,  0x7fb,      11);
+        addChar(44,  0xfa,        8);
+        addChar(45,  0x16,        6);
+        addChar(46,  0x17,        6);
+        addChar(47,  0x18,        6);
+        addChar(48,  0x0,         5);
+        addChar(49,  0x1,         5);
+        addChar(50,  0x2,         5);
+        addChar(51,  0x19,        6);
+        addChar(52,  0x1a,        6);
+        addChar(53,  0x1b,        6);
+        addChar(54,  0x1c,        6);
+        addChar(55,  0x1d,        6);
+        addChar(56,  0x1e,        6);
+        addChar(57,  0x1f,        6);
+        addChar(58,  0x5c,        7);
+        addChar(59,  0xfb,        8);
+        addChar(60,  0x7ffc,     15);
+        addChar(61,  0x20,        6);
+        addChar(62,  0xffb,      12);
+        addChar(63,  0x3fc,      10);
+        addChar(64,  0x1ffa,     13);
+        addChar(65,  0x21,        6);
+        addChar(66,  0x5d,        7);
+        addChar(67,  0x5e,        7);
+        addChar(68,  0x5f,        7);
+        addChar(69,  0x60,        7);
+        addChar(70,  0x61,        7);
+        addChar(71,  0x62,        7);
+        addChar(72,  0x63,        7);
+        addChar(73,  0x64,        7);
+        addChar(74,  0x65,        7);
+        addChar(75,  0x66,        7);
+        addChar(76,  0x67,        7);
+        addChar(77,  0x68,        7);
+        addChar(78,  0x69,        7);
+        addChar(79,  0x6a,        7);
+        addChar(80,  0x6b,        7);
+        addChar(81,  0x6c,        7);
+        addChar(82,  0x6d,        7);
+        addChar(83,  0x6e,        7);
+        addChar(84,  0x6f,        7);
+        addChar(85,  0x70,        7);
+        addChar(86,  0x71,        7);
+        addChar(87,  0x72,        7);
+        addChar(88,  0xfc,        8);
+        addChar(89,  0x73,        7);
+        addChar(90,  0xfd,        8);
+        addChar(91,  0x1ffb,     13);
+        addChar(92,  0x7fff0,    19);
+        addChar(93,  0x1ffc,     13);
+        addChar(94,  0x3ffc,     14);
+        addChar(95,  0x22,        6);
+        addChar(96,  0x7ffd,     15);
+        addChar(97,  0x3,         5);
+        addChar(98,  0x23,        6);
+        addChar(99,  0x4,         5);
+        addChar(100, 0x24,        6);
+        addChar(101, 0x5,         5);
+        addChar(102, 0x25,        6);
+        addChar(103, 0x26,        6);
+        addChar(104, 0x27,        6);
+        addChar(105, 0x6,         5);
+        addChar(106, 0x74,        7);
+        addChar(107, 0x75,        7);
+        addChar(108, 0x28,        6);
+        addChar(109, 0x29,        6);
+        addChar(110, 0x2a,        6);
+        addChar(111, 0x7,         5);
+        addChar(112, 0x2b,        6);
+        addChar(113, 0x76,        7);
+        addChar(114, 0x2c,        6);
+        addChar(115, 0x8,         5);
+        addChar(116, 0x9,         5);
+        addChar(117, 0x2d,        6);
+        addChar(118, 0x77,        7);
+        addChar(119, 0x78,        7);
+        addChar(120, 0x79,        7);
+        addChar(121, 0x7a,        7);
+        addChar(122, 0x7b,        7);
+        addChar(123, 0x7ffe,     15);
+        addChar(124, 0x7fc,      11);
+        addChar(125, 0x3ffd,     14);
+        addChar(126, 0x1ffd,     13);
+        addChar(127, 0xffffffc,  28);
+        addChar(128, 0xfffe6,    20);
+        addChar(129, 0x3fffd2,   22);
+        addChar(130, 0xfffe7,    20);
+        addChar(131, 0xfffe8,    20);
+        addChar(132, 0x3fffd3,   22);
+        addChar(133, 0x3fffd4,   22);
+        addChar(134, 0x3fffd5,   22);
+        addChar(135, 0x7fffd9,   23);
+        addChar(136, 0x3fffd6,   22);
+        addChar(137, 0x7fffda,   23);
+        addChar(138, 0x7fffdb,   23);
+        addChar(139, 0x7fffdc,   23);
+        addChar(140, 0x7fffdd,   23);
+        addChar(141, 0x7fffde,   23);
+        addChar(142, 0xffffeb,   24);
+        addChar(143, 0x7fffdf,   23);
+        addChar(144, 0xffffec,   24);
+        addChar(145, 0xffffed,   24);
+        addChar(146, 0x3fffd7,   22);
+        addChar(147, 0x7fffe0,   23);
+        addChar(148, 0xffffee,   24);
+        addChar(149, 0x7fffe1,   23);
+        addChar(150, 0x7fffe2,   23);
+        addChar(151, 0x7fffe3,   23);
+        addChar(152, 0x7fffe4,   23);
+        addChar(153, 0x1fffdc,   21);
+        addChar(154, 0x3fffd8,   22);
+        addChar(155, 0x7fffe5,   23);
+        addChar(156, 0x3fffd9,   22);
+        addChar(157, 0x7fffe6,   23);
+        addChar(158, 0x7fffe7,   23);
+        addChar(159, 0xffffef,   24);
+        addChar(160, 0x3fffda,   22);
+        addChar(161, 0x1fffdd,   21);
+        addChar(162, 0xfffe9,    20);
+        addChar(163, 0x3fffdb,   22);
+        addChar(164, 0x3fffdc,   22);
+        addChar(165, 0x7fffe8,   23);
+        addChar(166, 0x7fffe9,   23);
+        addChar(167, 0x1fffde,   21);
+        addChar(168, 0x7fffea,   23);
+        addChar(169, 0x3fffdd,   22);
+        addChar(170, 0x3fffde,   22);
+        addChar(171, 0xfffff0,   24);
+        addChar(172, 0x1fffdf,   21);
+        addChar(173, 0x3fffdf,   22);
+        addChar(174, 0x7fffeb,   23);
+        addChar(175, 0x7fffec,   23);
+        addChar(176, 0x1fffe0,   21);
+        addChar(177, 0x1fffe1,   21);
+        addChar(178, 0x3fffe0,   22);
+        addChar(179, 0x1fffe2,   21);
+        addChar(180, 0x7fffed,   23);
+        addChar(181, 0x3fffe1,   22);
+        addChar(182, 0x7fffee,   23);
+        addChar(183, 0x7fffef,   23);
+        addChar(184, 0xfffea,    20);
+        addChar(185, 0x3fffe2,   22);
+        addChar(186, 0x3fffe3,   22);
+        addChar(187, 0x3fffe4,   22);
+        addChar(188, 0x7ffff0,   23);
+        addChar(189, 0x3fffe5,   22);
+        addChar(190, 0x3fffe6,   22);
+        addChar(191, 0x7ffff1,   23);
+        addChar(192, 0x3ffffe0,  26);
+        addChar(193, 0x3ffffe1,  26);
+        addChar(194, 0xfffeb,    20);
+        addChar(195, 0x7fff1,    19);
+        addChar(196, 0x3fffe7,   22);
+        addChar(197, 0x7ffff2,   23);
+        addChar(198, 0x3fffe8,   22);
+        addChar(199, 0x1ffffec,  25);
+        addChar(200, 0x3ffffe2,  26);
+        addChar(201, 0x3ffffe3,  26);
+        addChar(202, 0x3ffffe4,  26);
+        addChar(203, 0x7ffffde,  27);
+        addChar(204, 0x7ffffdf,  27);
+        addChar(205, 0x3ffffe5,  26);
+        addChar(206, 0xfffff1,   24);
+        addChar(207, 0x1ffffed,  25);
+        addChar(208, 0x7fff2,    19);
+        addChar(209, 0x1fffe3,   21);
+        addChar(210, 0x3ffffe6,  26);
+        addChar(211, 0x7ffffe0,  27);
+        addChar(212, 0x7ffffe1,  27);
+        addChar(213, 0x3ffffe7,  26);
+        addChar(214, 0x7ffffe2,  27);
+        addChar(215, 0xfffff2,   24);
+        addChar(216, 0x1fffe4,   21);
+        addChar(217, 0x1fffe5,   21);
+        addChar(218, 0x3ffffe8,  26);
+        addChar(219, 0x3ffffe9,  26);
+        addChar(220, 0xffffffd,  28);
+        addChar(221, 0x7ffffe3,  27);
+        addChar(222, 0x7ffffe4,  27);
+        addChar(223, 0x7ffffe5,  27);
+        addChar(224, 0xfffec,    20);
+        addChar(225, 0xfffff3,   24);
+        addChar(226, 0xfffed,    20);
+        addChar(227, 0x1fffe6,   21);
+        addChar(228, 0x3fffe9,   22);
+        addChar(229, 0x1fffe7,   21);
+        addChar(230, 0x1fffe8,   21);
+        addChar(231, 0x7ffff3,   23);
+        addChar(232, 0x3fffea,   22);
+        addChar(233, 0x3fffeb,   22);
+        addChar(234, 0x1ffffee,  25);
+        addChar(235, 0x1ffffef,  25);
+        addChar(236, 0xfffff4,   24);
+        addChar(237, 0xfffff5,   24);
+        addChar(238, 0x3ffffea,  26);
+        addChar(239, 0x7ffff4,   23);
+        addChar(240, 0x3ffffeb,  26);
+        addChar(241, 0x7ffffe6,  27);
+        addChar(242, 0x3ffffec,  26);
+        addChar(243, 0x3ffffed,  26);
+        addChar(244, 0x7ffffe7,  27);
+        addChar(245, 0x7ffffe8,  27);
+        addChar(246, 0x7ffffe9,  27);
+        addChar(247, 0x7ffffea,  27);
+        addChar(248, 0x7ffffeb,  27);
+        addChar(249, 0xffffffe,  28);
+        addChar(250, 0x7ffffec,  27);
+        addChar(251, 0x7ffffed,  27);
+        addChar(252, 0x7ffffee,  27);
+        addChar(253, 0x7ffffef,  27);
+        addChar(254, 0x7fffff0,  27);
+        addChar(255, 0x3ffffee,  26);
+        addEOS (256, EOS.code,   EOS.length);
+        // @formatter:on
+    }
+
+
+    /**
+     * Calculates the number of bytes required to represent the given {@code
+     * CharSequence} with the Huffman coding.
+     *
+     * @param value
+     *         characters
+     *
+     * @return number of bytes
+     *
+     * @throws NullPointerException
+     *         if the value is null
+     */
+    public int lengthOf(CharSequence value) {
+        return lengthOf(value, 0, value.length());
+    }
+
+    /**
+     * Calculates the number of bytes required to represent a subsequence of the
+     * given {@code CharSequence} with the Huffman coding.
+     *
+     * @param value
+     *         characters
+     * @param start
+     *         the start index, inclusive
+     * @param end
+     *         the end index, exclusive
+     *
+     * @return number of bytes
+     *
+     * @throws NullPointerException
+     *         if the value is null
+     * @throws IndexOutOfBoundsException
+     *         if any invocation of {@code value.charAt(i)}, where {@code start
+     *         <= i < end} would throw an IndexOutOfBoundsException
+     */
+    public int lengthOf(CharSequence value, int start, int end) {
+        int len = 0;
+        for (int i = start; i < end; i++) {
+            char c = value.charAt(i);
+            len += INSTANCE.codeOf(c).length;
+        }
+        // Integer division with ceiling, assumption:
+        assert (len / 8 + (len % 8 != 0 ? 1 : 0)) == (len + 7) / 8 : len;
+        return (len + 7) / 8;
+    }
+
+    private void addChar(int c, int code, int bitLength) {
+        addLeaf(c, code, bitLength, false);
+        codes[c] = new Code(code, bitLength);
+    }
+
+    private void addEOS(int c, int code, int bitLength) {
+        addLeaf(c, code, bitLength, true);
+        codes[c] = new Code(code, bitLength);
+    }
+
+    private void addLeaf(int c, int code, int bitLength, boolean isEOS) {
+        if (bitLength < 1) {
+            throw new IllegalArgumentException("bitLength < 1");
+        }
+        Node curr = root;
+        for (int p = 1 << bitLength - 1; p != 0 && !curr.isLeaf(); p = p >> 1) {
+            curr.isEOSPath |= isEOS; // If it's already true, it can't become false
+            curr = curr.addChildIfAbsent(p & code);
+        }
+        curr.isEOSPath |= isEOS; // The last one needs to have this property as well
+        if (curr.isLeaf()) {
+            throw new IllegalStateException("Specified code is already taken");
+        }
+        curr.setChar((char) c);
+    }
+
+    private Code codeOf(char c) {
+        if (c > 255) {
+            throw new IllegalArgumentException("char=" + ((int) c));
+        }
+        return codes[c];
+    }
+
+    //
+    // For debugging/testing purposes
+    //
+    Node getRoot() {
+        return root;
+    }
+
+    //
+    // Guarantees:
+    //
+    //  if (isLeaf() == true) => getChar() is a legal call
+    //  if (isLeaf() == false) => getChild(i) is a legal call (though it can
+    //                                                           return null)
+    //
+    static class Node {
+
+        Node left;
+        Node right;
+        boolean isEOSPath;
+
+        boolean charIsSet;
+        char c;
+
+        Node getChild(int selector) {
+            if (isLeaf()) {
+                throw new IllegalStateException("This is a leaf node");
+            }
+            Node result = selector == 0 ? left : right;
+            if (result == null) {
+                throw new IllegalStateException(format(
+                        "Node doesn't have a child (selector=%s)", selector));
+            }
+            return result;
+        }
+
+        boolean isLeaf() {
+            return charIsSet;
+        }
+
+        char getChar() {
+            if (!isLeaf()) {
+                throw new IllegalStateException("This node is not a leaf node");
+            }
+            return c;
+        }
+
+        void setChar(char c) {
+            if (charIsSet) {
+                throw new IllegalStateException(
+                        "This node has been taken already");
+            }
+            if (left != null || right != null) {
+                throw new IllegalStateException("The node cannot be made "
+                        + "a leaf as it's already has a child");
+            }
+            this.c = c;
+            charIsSet = true;
+        }
+
+        Node addChildIfAbsent(int i) {
+            if (charIsSet) {
+                throw new IllegalStateException("The node cannot have a child "
+                        + "as it's already a leaf node");
+            }
+            Node child;
+            if (i == 0) {
+                if ((child = left) == null) {
+                    child = left = new Node();
+                }
+            } else {
+                if ((child = right) == null) {
+                    child = right = new Node();
+                }
+            }
+            return child;
+        }
+
+        @Override
+        public String toString() {
+            if (isLeaf()) {
+                if (isEOSPath) {
+                    return "EOS";
+                } else {
+                    return format("char: (%3s) '%s'", (int) c, c);
+                }
+            }
+            return "/\\";
+        }
+    }
+
+    // TODO: value-based class?
+    // FIXME: can we re-use Node instead of this class?
+    private static final class Code {
+
+        final int code;
+        final int length;
+
+        private Code(int code, int length) {
+            this.code = code;
+            this.length = length;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public int getLength() {
+            return length;
+        }
+
+        @Override
+        public String toString() {
+            long p = 1 << length;
+            return Long.toBinaryString(code + p).substring(1)
+                    + ", length=" + length;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/ISO_8859_1.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
+//
+// Custom implementation of ISO/IEC 8859-1:1998
+//
+// The rationale behind this is not to deal with CharsetEncoder/CharsetDecoder,
+// basically because it would require wrapping every single CharSequence into a
+// CharBuffer and then copying it back.
+//
+// But why not to give a CharBuffer instead of Appendable? Because I can choose
+// an Appendable (e.g. StringBuilder) that adjusts its length when needed and
+// therefore not to deal with pre-sized CharBuffers or copying.
+//
+// The encoding is simple and well known: 1 byte <-> 1 char
+//
+final class ISO_8859_1 {
+
+    private ISO_8859_1() { }
+
+    public static final class Reader {
+
+        public void read(ByteBuffer source, Appendable destination) {
+            for (int i = 0, len = source.remaining(); i < len; i++) {
+                char c = (char) (source.get() & 0xff);
+                try {
+                    destination.append(c);
+                } catch (IOException e) {
+                    throw new UncheckedIOException
+                            ("Error appending to the destination", e);
+                }
+            }
+        }
+
+        public Reader reset() {
+            return this;
+        }
+    }
+
+    public static final class Writer {
+
+        private CharSequence source;
+        private int pos;
+        private int end;
+
+        public Writer configure(CharSequence source, int start, int end) {
+            this.source = source;
+            this.pos = start;
+            this.end = end;
+            return this;
+        }
+
+        public boolean write(ByteBuffer destination) {
+            for (; pos < end; pos++) {
+                char c = source.charAt(pos);
+                if (c > '\u00FF') {
+                    throw new IllegalArgumentException(
+                            "Illegal ISO-8859-1 char: " + (int) c);
+                }
+                if (destination.hasRemaining()) {
+                    destination.put((byte) c);
+                } else {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public Writer reset() {
+            source = null;
+            pos = -1;
+            end = -1;
+            return this;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/IndexNameValueWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+
+abstract class IndexNameValueWriter implements BinaryRepresentationWriter {
+
+    private final int pattern;
+    private final int prefix;
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private final StringWriter nameWriter = new StringWriter();
+    private final StringWriter valueWriter = new StringWriter();
+
+    protected boolean indexedRepresentation;
+
+    private static final int NEW               = 0;
+    private static final int NAME_PART_WRITTEN = 1;
+    private static final int VALUE_WRITTEN     = 2;
+
+    private int state = NEW;
+
+    protected IndexNameValueWriter(int pattern, int prefix) {
+        this.pattern = pattern;
+        this.prefix = prefix;
+    }
+
+    IndexNameValueWriter index(int index) {
+        indexedRepresentation = true;
+        intWriter.configure(index, prefix, pattern);
+        return this;
+    }
+
+    IndexNameValueWriter name(CharSequence name, boolean useHuffman) {
+        indexedRepresentation = false;
+        intWriter.configure(0, prefix, pattern);
+        nameWriter.configure(name, useHuffman);
+        return this;
+    }
+
+    IndexNameValueWriter value(CharSequence value, boolean useHuffman) {
+        valueWriter.configure(value, useHuffman);
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (state < NAME_PART_WRITTEN) {
+            if (indexedRepresentation) {
+                if (!intWriter.write(destination)) {
+                    return false;
+                }
+            } else {
+                if (!intWriter.write(destination) || !nameWriter.write(destination)) {
+                    return false;
+                }
+            }
+            state = NAME_PART_WRITTEN;
+        }
+        if (state < VALUE_WRITTEN) {
+            if (!valueWriter.write(destination)) {
+                return false;
+            }
+            state = VALUE_WRITTEN;
+        }
+        return state == VALUE_WRITTEN;
+    }
+
+    @Override
+    public IndexNameValueWriter reset() {
+        intWriter.reset();
+        if (!indexedRepresentation) {
+            nameWriter.reset();
+        }
+        valueWriter.reset();
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/IndexedWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+
+final class IndexedWriter implements BinaryRepresentationWriter {
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+
+    IndexedWriter() { }
+
+    IndexedWriter index(int index) {
+        intWriter.configure(index, 7, 0b1000_0000);
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        return intWriter.write(destination);
+    }
+
+    @Override
+    public BinaryRepresentationWriter reset() {
+        intWriter.reset();
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/IntegerReader.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import static java.lang.String.format;
+
+final class IntegerReader {
+
+    private static final int NEW             = 0;
+    private static final int CONFIGURED      = 1;
+    private static final int FIRST_BYTE_READ = 2;
+    private static final int DONE            = 4;
+
+    private int state = NEW;
+
+    private int N;
+    private int maxValue;
+    private int value;
+    private long r;
+    private long b = 1;
+
+    public IntegerReader configure(int N) {
+        return configure(N, Integer.MAX_VALUE);
+    }
+
+    //
+    // Why is it important to configure 'maxValue' here. After all we can wait
+    // for the integer to be fully read and then check it. Can't we?
+    //
+    // Two reasons.
+    //
+    // 1. Value wraps around long won't be unnoticed.
+    // 2. It can spit out an exception as soon as it becomes clear there's
+    // an overflow. Therefore, no need to wait for the value to be fully read.
+    //
+    public IntegerReader configure(int N, int maxValue) {
+        if (state != NEW) {
+            throw new IllegalStateException("Already configured");
+        }
+        checkPrefix(N);
+        if (maxValue < 0) {
+            throw new IllegalArgumentException(
+                    "maxValue >= 0: maxValue=" + maxValue);
+        }
+        this.maxValue = maxValue;
+        this.N = N;
+        state = CONFIGURED;
+        return this;
+    }
+
+    public boolean read(ByteBuffer input) {
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (state == DONE) {
+            return true;
+        }
+        if (!input.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            int max = (2 << (N - 1)) - 1;
+            int n = input.get() & max;
+            if (n != max) {
+                value = n;
+                state = DONE;
+                return true;
+            } else {
+                r = max;
+            }
+            state = FIRST_BYTE_READ;
+        }
+        if (state == FIRST_BYTE_READ) {
+            // variable-length quantity (VLQ)
+            byte i;
+            do {
+                if (!input.hasRemaining()) {
+                    return false;
+                }
+                i = input.get();
+                long increment = b * (i & 127);
+                if (r + increment > maxValue) {
+                    throw new IllegalArgumentException(format(
+                            "Integer overflow: maxValue=%,d, value=%,d",
+                            maxValue, r + increment));
+                }
+                r += increment;
+                b *= 128;
+            } while ((128 & i) == 128);
+
+            value = (int) r;
+            state = DONE;
+            return true;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, N, maxValue, value, r, b}));
+    }
+
+    public int get() throws IllegalStateException {
+        if (state != DONE) {
+            throw new IllegalStateException("Has not been fully read yet");
+        }
+        return value;
+    }
+
+    private static void checkPrefix(int N) {
+        if (N < 1 || N > 8) {
+            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
+        }
+    }
+
+    public IntegerReader reset() {
+        b = 1;
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/IntegerWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+final class IntegerWriter {
+
+    private static final int NEW                = 0;
+    private static final int CONFIGURED         = 1;
+    private static final int FIRST_BYTE_WRITTEN = 2;
+    private static final int DONE               = 4;
+
+    private int state = NEW;
+
+    private int payload;
+    private int N;
+    private int value;
+
+    //
+    //      0   1   2   3   4   5   6   7
+    //    +---+---+---+---+---+---+---+---+
+    //    |   |   |   |   |   |   |   |   |
+    //    +---+---+---+-------------------+
+    //    |<--------->|<----------------->|
+    //       payload           N=5
+    //
+    // payload is the contents of the left-hand side part of the octet;
+    //         it is truncated to fit into 8-N bits, where 1 <= N <= 8;
+    //
+    public IntegerWriter configure(int value, int N, int payload) {
+        if (state != NEW) {
+            throw new IllegalStateException("Already configured");
+        }
+        if (value < 0) {
+            throw new IllegalArgumentException("value >= 0: value=" + value);
+        }
+        checkPrefix(N);
+        this.value = value;
+        this.N = N;
+        this.payload = payload & 0xFF & (0xFFFFFFFF << N);
+        state = CONFIGURED;
+        return this;
+    }
+
+    public boolean write(ByteBuffer output) {
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (state == DONE) {
+            return true;
+        }
+
+        if (!output.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            int max = (2 << (N - 1)) - 1;
+            if (value < max) {
+                output.put((byte) (payload | value));
+                state = DONE;
+                return true;
+            }
+            output.put((byte) (payload | max));
+            value -= max;
+            state = FIRST_BYTE_WRITTEN;
+        }
+        if (state == FIRST_BYTE_WRITTEN) {
+            while (value >= 128 && output.hasRemaining()) {
+                output.put((byte) (value % 128 + 128));
+                value /= 128;
+            }
+            if (!output.hasRemaining()) {
+                return false;
+            }
+            output.put((byte) value);
+            state = DONE;
+            return true;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, payload, N, value}));
+    }
+
+    private static void checkPrefix(int N) {
+        if (N < 1 || N > 8) {
+            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
+        }
+    }
+
+    public IntegerWriter reset() {
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/LiteralNeverIndexedWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+final class LiteralNeverIndexedWriter extends IndexNameValueWriter {
+
+    LiteralNeverIndexedWriter() {
+        super(0b0001_0000, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/LiteralWithIndexingWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+
+final class LiteralWithIndexingWriter extends IndexNameValueWriter {
+
+    private boolean tableUpdated;
+
+    private CharSequence name;
+    private CharSequence value;
+    private int index;
+
+    LiteralWithIndexingWriter() {
+        super(0b0100_0000, 6);
+    }
+
+    @Override
+    LiteralWithIndexingWriter index(int index) {
+        super.index(index);
+        this.index = index;
+        return this;
+    }
+
+    @Override
+    LiteralWithIndexingWriter name(CharSequence name, boolean useHuffman) {
+        super.name(name, useHuffman);
+        this.name = name;
+        return this;
+    }
+
+    @Override
+    LiteralWithIndexingWriter value(CharSequence value, boolean useHuffman) {
+        super.value(value, useHuffman);
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!tableUpdated) {
+            CharSequence n;
+            if (indexedRepresentation) {
+                n = table.get(index).name;
+            } else {
+                n = name;
+            }
+            table.put(n, value);
+            tableUpdated = true;
+        }
+        return super.write(table, destination);
+    }
+
+    @Override
+    public IndexNameValueWriter reset() {
+        tableUpdated = false;
+        name = null;
+        value = null;
+        index = -1;
+        return super.reset();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/LiteralWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+final class LiteralWriter extends IndexNameValueWriter {
+
+    LiteralWriter() {
+        super(0b0000_0000, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/SizeUpdateWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+
+final class SizeUpdateWriter implements BinaryRepresentationWriter {
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private int maxSize;
+    private boolean tableUpdated;
+
+    SizeUpdateWriter() { }
+
+    SizeUpdateWriter maxHeaderTableSize(int size) {
+        intWriter.configure(size, 5, 0b0010_0000);
+        this.maxSize = size;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!tableUpdated) {
+            table.setMaxSize(maxSize);
+            tableUpdated = true;
+        }
+        return intWriter.write(destination);
+    }
+
+    @Override
+    public BinaryRepresentationWriter reset() {
+        intWriter.reset();
+        maxSize = -1;
+        tableUpdated = false;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/StringReader.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+//
+//          0   1   2   3   4   5   6   7
+//        +---+---+---+---+---+---+---+---+
+//        | H |    String Length (7+)     |
+//        +---+---------------------------+
+//        |  String Data (Length octets)  |
+//        +-------------------------------+
+//
+final class StringReader {
+
+    private static final int NEW             = 0;
+    private static final int FIRST_BYTE_READ = 1;
+    private static final int LENGTH_READ     = 2;
+    private static final int DONE            = 4;
+
+    private final IntegerReader intReader = new IntegerReader();
+    private final Huffman.Reader huffmanReader = new Huffman.Reader();
+    private final ISO_8859_1.Reader plainReader = new ISO_8859_1.Reader();
+
+    private int state = NEW;
+
+    private boolean huffman;
+    private int remainingLength;
+
+    boolean read(ByteBuffer input, Appendable output) {
+        if (state == DONE) {
+            return true;
+        }
+        if (!input.hasRemaining()) {
+            return false;
+        }
+        if (state == NEW) {
+            int p = input.position();
+            huffman = (input.get(p) & 0b10000000) != 0;
+            state = FIRST_BYTE_READ;
+            intReader.configure(7);
+        }
+        if (state == FIRST_BYTE_READ) {
+            boolean lengthRead = intReader.read(input);
+            if (!lengthRead) {
+                return false;
+            }
+            remainingLength = intReader.get();
+            state = LENGTH_READ;
+        }
+        if (state == LENGTH_READ) {
+            boolean isLast = input.remaining() >= remainingLength;
+            int oldLimit = input.limit();
+            if (isLast) {
+                input.limit(input.position() + remainingLength);
+            }
+            remainingLength -= Math.min(input.remaining(), remainingLength);
+            if (huffman) {
+                huffmanReader.read(input, output, isLast);
+            } else {
+                plainReader.read(input, output);
+            }
+            if (isLast) {
+                input.limit(oldLimit);
+                state = DONE;
+            }
+            return isLast;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, huffman, remainingLength}));
+    }
+
+    boolean isHuffmanEncoded() {
+        if (state < FIRST_BYTE_READ) {
+            throw new IllegalStateException("Has not been fully read yet");
+        }
+        return huffman;
+    }
+
+    void reset() {
+        if (huffman) {
+            huffmanReader.reset();
+        } else {
+            plainReader.reset();
+        }
+        intReader.reset();
+        state = NEW;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/StringWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+//
+//          0   1   2   3   4   5   6   7
+//        +---+---+---+---+---+---+---+---+
+//        | H |    String Length (7+)     |
+//        +---+---------------------------+
+//        |  String Data (Length octets)  |
+//        +-------------------------------+
+//
+// StringWriter does not require a notion of endOfInput (isLast) in 'write'
+// methods due to the nature of string representation in HPACK. Namely, the
+// length of the string is put before string's contents. Therefore the length is
+// always known beforehand.
+//
+// Expected use:
+//
+//     configure write* (reset configure write*)*
+//
+final class StringWriter {
+
+    private static final int NEW            = 0;
+    private static final int CONFIGURED     = 1;
+    private static final int LENGTH_WRITTEN = 2;
+    private static final int DONE           = 4;
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private final Huffman.Writer huffmanWriter = new Huffman.Writer();
+    private final ISO_8859_1.Writer plainWriter = new ISO_8859_1.Writer();
+
+    private int state = NEW;
+    private boolean huffman;
+
+    StringWriter configure(CharSequence input, boolean huffman) {
+        return configure(input, 0, input.length(), huffman);
+    }
+
+    StringWriter configure(CharSequence input, int start, int end,
+                           boolean huffman) {
+        if (start < 0 || end < 0 || end > input.length() || start > end) {
+            throw new IndexOutOfBoundsException(
+                    String.format("input.length()=%s, start=%s, end=%s",
+                            input.length(), start, end));
+        }
+        if (!huffman) {
+            plainWriter.configure(input, start, end);
+            intWriter.configure(end - start, 7, 0b0000_0000);
+        } else {
+            huffmanWriter.from(input, start, end);
+            intWriter.configure(Huffman.INSTANCE.lengthOf(input, start, end),
+                    7, 0b1000_0000);
+        }
+
+        this.huffman = huffman;
+        state = CONFIGURED;
+        return this;
+    }
+
+    boolean write(ByteBuffer output) {
+        if (state == DONE) {
+            return true;
+        }
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (!output.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            if (intWriter.write(output)) {
+                state = LENGTH_WRITTEN;
+            } else {
+                return false;
+            }
+        }
+        if (state == LENGTH_WRITTEN) {
+            boolean written = huffman
+                    ? huffmanWriter.write(output)
+                    : plainWriter.write(output);
+            if (written) {
+                state = DONE;
+                return true;
+            } else {
+                return false;
+            }
+        }
+        throw new InternalError(Arrays.toString(new Object[]{state, huffman}));
+    }
+
+    void reset() {
+        intWriter.reset();
+        if (huffman) {
+            huffmanWriter.reset();
+        } else {
+            plainWriter.reset();
+        }
+        state = NEW;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/package-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * HPACK (Header Compression for HTTP/2) implementation conforming to
+ * <a href="https://tools.ietf.org/html/rfc7541">RFC&nbsp;7541</a>.
+ *
+ * <p> Headers can be decoded and encoded by {@link jdk.incubator.http.internal.hpack.Decoder}
+ * and {@link jdk.incubator.http.internal.hpack.Encoder} respectively.
+ *
+ * <p> Instances of these classes are not safe for use by multiple threads.
+ */
+package jdk.incubator.http.internal.hpack;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/BuilderImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.WebSocket;
+import jdk.incubator.http.WebSocket.Builder;
+import jdk.incubator.http.WebSocket.Listener;
+import jdk.incubator.http.internal.common.Pair;
+
+import java.net.URI;
+import java.time.Duration;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import static java.util.Objects.requireNonNull;
+import static jdk.incubator.http.internal.common.Pair.pair;
+
+public final class BuilderImpl implements Builder {
+
+    private final HttpClient client;
+    private final URI uri;
+    private final Listener listener;
+    private final List<Pair<String, String>> headers = new LinkedList<>();
+    private final Collection<String> subprotocols = new LinkedList<>();
+    private Duration timeout;
+
+    public BuilderImpl(HttpClient client, URI uri, Listener listener) {
+        this.client = requireNonNull(client, "client");
+        this.uri = requireNonNull(uri, "uri");
+        this.listener = requireNonNull(listener, "listener");
+    }
+
+    @Override
+    public Builder header(String name, String value) {
+        requireNonNull(name, "name");
+        requireNonNull(value, "value");
+        headers.add(pair(name, value));
+        return this;
+    }
+
+    @Override
+    public Builder subprotocols(String mostPreferred, String... lesserPreferred)
+    {
+        requireNonNull(mostPreferred, "mostPreferred");
+        requireNonNull(lesserPreferred, "lesserPreferred");
+        List<String> subprotocols = new LinkedList<>();
+        for (int i = 0; i < lesserPreferred.length; i++) {
+            String p = lesserPreferred[i];
+            requireNonNull(p, "lesserPreferred[" + i + "]");
+            subprotocols.add(p);
+        }
+        subprotocols.add(0, mostPreferred);
+        this.subprotocols.clear();
+        this.subprotocols.addAll(subprotocols);
+        return this;
+    }
+
+    @Override
+    public Builder connectTimeout(Duration timeout) {
+        this.timeout = requireNonNull(timeout, "timeout");
+        return this;
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> buildAsync() {
+        return WebSocketImpl.newInstanceAsync(this);
+    }
+
+    HttpClient getClient() { return client; }
+
+    URI getUri() { return uri; }
+
+    Listener getListener() { return listener; }
+
+    List<Pair<String, String>> getHeaders() { return headers; }
+
+    Collection<String> getSubprotocols() { return subprotocols; }
+
+    Duration getConnectTimeout() { return timeout; }
+
+    @Override
+    public String toString() {
+        return "WebSocket.Builder{"
+                + ", uri=" + uri
+                + ", listener=" + listener
+                + (!headers.isEmpty() ? ", headers=" + headers : "")
+                + (!subprotocols.isEmpty() ? ", subprotocols=" + subprotocols : "")
+                + ( timeout != null ? ", connectTimeout=" + timeout : "")
+                + '}';
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/CheckFailedException.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http.internal.websocket;
+
+/*
+ * Used as a context-neutral exception which can be wrapped into (for example)
+ * a `ProtocolException` or an `IllegalArgumentException` depending on who's
+ * doing the check.
+ */
+final class CheckFailedException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    CheckFailedException(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/CooperativeHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http.internal.websocket;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import static java.util.Objects.requireNonNull;
+
+final class CooperativeHandler {
+
+    private static final long CONTINUE = 0;
+    private static final long OFF      = 1;
+    private static final long ON       = 2;
+    private static final long STOP     = 4;
+
+    private final AtomicLong state = new AtomicLong(OFF);
+
+    private final Runnable task;
+
+    CooperativeHandler(Runnable task) {
+        this.task = requireNonNull(task);
+    }
+
+    /*
+     * Causes the task supplied to the constructor to run. The task may be run
+     * by this thread as well as by any other that has invoked this method.
+     *
+     * The recursion which is possible here will have the maximum depth of 1:
+     *
+     *     task.run()
+     *         this.startOrContinue()
+     *             task.run()
+     */
+    void startOrContinue() {
+        long s;
+        while (true) {
+            s = state.get();
+            if (s == OFF && state.compareAndSet(OFF, ON)) {
+                // No one is running the task, we are going to run it
+                break;
+            }
+            if (s == ON && state.compareAndSet(ON, CONTINUE)) {
+                // Some other thread is running the task. We have managed to
+                // update the state, it will be surely noticed by that thread.
+                return;
+            }
+            if (s == CONTINUE || s == STOP) {
+                return;
+            }
+        }
+        while (true) {
+            task.run();
+            // State checks are ordered by the probability of expected values
+            // (it might be different in different usage patterns, say, when
+            // invocations to `startOrContinue()` are concurrent)
+            if (state.compareAndSet(ON, OFF)) {
+                break; // The state hasn't changed, all done
+            }
+            if (state.compareAndSet(CONTINUE, ON)) {
+                continue;
+            }
+            // Other threads can change the state from CONTINUE to STOP only
+            // So if it's not ON and not CONTINUE, it can only be STOP
+            break;
+        }
+    }
+
+    void stop() {
+        state.set(STOP);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/FailWebSocketException.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import static jdk.incubator.http.internal.websocket.StatusCodes.PROTOCOL_ERROR;
+
+/*
+ * Used as a marker for protocol issues in the incoming data, so that the
+ * implementation could "Fail the WebSocket Connection" with a status code in
+ * the Close message that fits the situation the most.
+ *
+ *     https://tools.ietf.org/html/rfc6455#section-7.1.7
+ */
+final class FailWebSocketException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+    private final int statusCode;
+
+    FailWebSocketException(String detail) {
+        this(detail, PROTOCOL_ERROR);
+    }
+
+    FailWebSocketException(String detail, int statusCode) {
+        super(detail);
+        this.statusCode = statusCode;
+    }
+
+    int getStatusCode() {
+        return statusCode;
+    }
+
+    @Override
+    public FailWebSocketException initCause(Throwable cause) {
+        return (FailWebSocketException) super.initCause(cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/Frame.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import java.nio.ByteBuffer;
+
+import static jdk.incubator.http.internal.common.Utils.dump;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.ofCode;
+
+/*
+ * A collection of utilities for reading, writing, and masking frames.
+ */
+final class Frame {
+
+    private Frame() { }
+
+    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) {
+                opcodes[c.code] = c;
+            }
+        }
+
+        private final byte code;
+
+        Opcode(int code) {
+            this.code = (byte) code;
+        }
+
+        boolean isControl() {
+            return (code & 0x8) != 0;
+        }
+
+        static Opcode ofCode(int code) {
+            return opcodes[code & 0xF];
+        }
+    }
+
+    /*
+     * A utility for masking frame payload data.
+     */
+    static final class Masker {
+
+        // Exploiting ByteBuffer's ability to read/write multi-byte integers
+        private final ByteBuffer acc = ByteBuffer.allocate(8);
+        private final int[] maskBytes = new int[4];
+        private int offset;
+        private long maskLong;
+
+        /*
+         * Reads all remaining bytes from the given input buffer, masks them
+         * with the supplied mask and writes the resulting bytes to the given
+         * output buffer.
+         *
+         * The source and the destination buffers may be the same instance.
+         */
+        static void transferMasking(ByteBuffer src, ByteBuffer dst, int mask) {
+            if (src.remaining() > dst.remaining()) {
+                throw new IllegalArgumentException(dump(src, dst));
+            }
+            new Masker().mask(mask).transferMasking(src, dst);
+        }
+
+        /*
+         * Clears this instance's state and sets the mask.
+         *
+         * The behaviour is as if the mask was set on a newly created instance.
+         */
+        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 remaining bytes as possible from the given input
+         * buffer, masks them with the previously set mask and writes the
+         * resulting bytes to the given output buffer.
+         *
+         * The source and the destination buffers may be the same instance. If
+         * the mask hasn't been previously set it is assumed to be 0.
+         */
+        Masker transferMasking(ByteBuffer src, ByteBuffer dst) {
+            begin(src, dst);
+            loop(src, dst);
+            end(src, dst);
+            return this;
+        }
+
+        /*
+         * Applies up to 3 remaining from the previous pass bytes of the mask.
+         */
+        private void begin(ByteBuffer src, ByteBuffer dst) {
+            if (offset == 0) { // No partially applied mask from the previous invocation
+                return;
+            }
+            int i = src.position(), j = dst.position();
+            final int srcLim = src.limit(), dstLim = dst.limit();
+            for (; offset < 4 && i < srcLim && j < dstLim; i++, j++, offset++)
+            {
+                dst.put(j, (byte) (src.get(i) ^ maskBytes[offset]));
+            }
+            offset &= 3; // Will become 0 if the mask has been fully applied
+            src.position(i);
+            dst.position(j);
+        }
+
+        /*
+         * Gallops one long (mask + mask) at a time.
+         */
+        private void loop(ByteBuffer src, ByteBuffer dst) {
+            int i = src.position();
+            int j = dst.position();
+            final int srcLongLim = src.limit() - 7, dstLongLim = dst.limit() - 7;
+            for (; i < srcLongLim && j < dstLongLim; 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);
+            }
+        }
+
+        /*
+         * Applies up to 7 remaining from the "galloping" phase bytes of the
+         * mask.
+         */
+        private void end(ByteBuffer src, ByteBuffer dst) {
+            assert Math.min(src.remaining(), dst.remaining()) < 8;
+            final int srcLim = src.limit(), dstLim = dst.limit();
+            int i = src.position(), j = dst.position();
+            for (; i < srcLim && j < dstLim;
+                 i++, j++, offset = (offset + 1) & 3) // offset cycles through 0..3
+            {
+                dst.put(j, (byte) (src.get(i) ^ maskBytes[offset]));
+            }
+            src.position(i);
+            dst.position(j);
+        }
+    }
+
+    /*
+     * A builder-style writer of frame headers.
+     *
+     * The writer does not enforce any protocol-level rules, it simply writes a
+     * header structure to the given buffer. The order of calls to intermediate
+     * methods is NOT significant.
+     */
+    static final class HeaderWriter {
+
+        private char firstChar;
+        private long payloadLen;
+        private int maskingKey;
+        private boolean mask;
+
+        HeaderWriter fin(boolean value) {
+            if (value) {
+                firstChar |=  0b10000000_00000000;
+            } else {
+                firstChar &= ~0b10000000_00000000;
+            }
+            return this;
+        }
+
+        HeaderWriter rsv1(boolean value) {
+            if (value) {
+                firstChar |=  0b01000000_00000000;
+            } else {
+                firstChar &= ~0b01000000_00000000;
+            }
+            return this;
+        }
+
+        HeaderWriter rsv2(boolean value) {
+            if (value) {
+                firstChar |=  0b00100000_00000000;
+            } else {
+                firstChar &= ~0b00100000_00000000;
+            }
+            return this;
+        }
+
+        HeaderWriter rsv3(boolean value) {
+            if (value) {
+                firstChar |=  0b00010000_00000000;
+            } else {
+                firstChar &= ~0b00010000_00000000;
+            }
+            return this;
+        }
+
+        HeaderWriter opcode(Opcode value) {
+            firstChar = (char) ((firstChar & 0xF0FF) | (value.code << 8));
+            return this;
+        }
+
+        HeaderWriter payloadLen(long value) {
+            if (value < 0) {
+                throw new IllegalArgumentException("Negative: " + value);
+            }
+            payloadLen = value;
+            firstChar &= 0b11111111_10000000; // Clear previous payload length leftovers
+            if (payloadLen < 126) {
+                firstChar |= payloadLen;
+            } else if (payloadLen < 65536) {
+                firstChar |= 126;
+            } else {
+                firstChar |= 127;
+            }
+            return this;
+        }
+
+        HeaderWriter mask(int value) {
+            firstChar |= 0b00000000_10000000;
+            maskingKey = value;
+            mask = true;
+            return this;
+        }
+
+        HeaderWriter 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 write(ByteBuffer buffer) {
+            buffer.putChar(firstChar);
+            if (payloadLen >= 126) {
+                if (payloadLen < 65536) {
+                    buffer.putChar((char) payloadLen);
+                } else {
+                    buffer.putLong(payloadLen);
+                }
+            }
+            if (mask) {
+                buffer.putInt(maskingKey);
+            }
+        }
+    }
+
+    /*
+     * A consumer of frame parts.
+     *
+     * Frame.Reader invokes the consumer's methods in the following order:
+     *
+     *     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 by the Frame.Reader when a part of the (or a complete) payload
+         * is ready to be consumed.
+         *
+         * The sum of numbers of bytes consumed in each invocation of this
+         * method corresponding to the given frame WILL be equal to
+         * 'payloadLen', reported to `void payloadLen(long value)` before that.
+         *
+         * In particular, if `payloadLen` is 0, then there WILL be a single
+         * invocation to this method.
+         *
+         * No unmasking is done.
+         */
+        void payloadData(ByteBuffer data);
+
+        void endFrame();
+    }
+
+    /*
+     * A Reader of frames.
+     *
+     * No protocol-level rules are checked.
+     */
+    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;
+
+        // Exploiting ByteBuffer's ability to read multi-byte integers
+        private final ByteBuffer accumulator = ByteBuffer.allocate(8);
+        private int state = AWAITING_FIRST_BYTE;
+        private boolean mask;
+        private long remainingPayloadLength;
+
+        /*
+         * Reads at most one frame from the given buffer invoking the consumer's
+         * methods corresponding to the frame parts found.
+         *
+         * As much of the frame's payload, if any, is read. The buffer's
+         * position is updated to reflect the number of bytes read.
+         *
+         * Throws FailWebSocketException if detects the frame is malformed.
+         */
+        void readFrame(ByteBuffer input, Consumer consumer) {
+            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(remainingPayloadLength = 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;
+                        }
+                        remainingPayloadLength = accumulator.flip().getChar();
+                        if (remainingPayloadLength < 126) {
+                            throw notMinimalEncoding(remainingPayloadLength);
+                        }
+                        consumer.payloadLen(remainingPayloadLength);
+                        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;
+                        }
+                        remainingPayloadLength = accumulator.flip().getLong();
+                        if (remainingPayloadLength < 0) {
+                            throw negativePayload(remainingPayloadLength);
+                        } else if (remainingPayloadLength < 65536) {
+                            throw notMinimalEncoding(remainingPayloadLength);
+                        }
+                        consumer.payloadLen(remainingPayloadLength);
+                        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
+                        int deliverable = (int) Math.min(remainingPayloadLength,
+                                                         input.remaining());
+                        int oldLimit = input.limit();
+                        input.limit(input.position() + deliverable);
+                        if (deliverable != 0 || remainingPayloadLength == 0) {
+                            consumer.payloadData(input);
+                        }
+                        int consumed = deliverable - input.remaining();
+                        if (consumed < 0) {
+                            // Consumer cannot consume more than there was available
+                            throw new InternalError();
+                        }
+                        input.limit(oldLimit);
+                        remainingPayloadLength -= consumed;
+                        if (remainingPayloadLength == 0) {
+                            consumer.endFrame();
+                            state = AWAITING_FIRST_BYTE;
+                        }
+                        break loop;
+                    default:
+                        throw new InternalError(String.valueOf(state));
+                }
+            }
+        }
+
+        private static FailWebSocketException negativePayload(long payloadLength)
+        {
+            return new FailWebSocketException(
+                    "Negative payload length: " + payloadLength);
+        }
+
+        private static FailWebSocketException notMinimalEncoding(long payloadLength)
+        {
+            return new FailWebSocketException(
+                    "Not minimally-encoded payload length:" + payloadLength);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/FrameConsumer.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.WebSocket.MessagePart;
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+
+import static java.lang.String.format;
+import static java.lang.System.Logger.Level.TRACE;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Objects.requireNonNull;
+import static jdk.incubator.http.internal.common.Utils.dump;
+import static jdk.incubator.http.internal.websocket.StatusCodes.NO_STATUS_CODE;
+import static jdk.incubator.http.internal.websocket.StatusCodes.checkIncomingCode;
+import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
+
+/*
+ * 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.
+ */
+/* Non-final for testing purposes only */
+class FrameConsumer implements Frame.Consumer {
+
+    private final MessageStreamConsumer output;
+    private final UTF8AccumulatingDecoder decoder = new UTF8AccumulatingDecoder();
+    private boolean fin;
+    private Opcode opcode, originatingOpcode;
+    private MessagePart part = MessagePart.WHOLE;
+    private long payloadLen;
+    private long unconsumedPayloadLen;
+    private ByteBuffer binaryData;
+
+    FrameConsumer(MessageStreamConsumer output) {
+        this.output = requireNonNull(output);
+    }
+
+    /* Exposed for testing purposes only */
+    MessageStreamConsumer getOutput() {
+        return output;
+    }
+
+    @Override
+    public void fin(boolean value) {
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading fin: {0}", value);
+        }
+        fin = value;
+    }
+
+    @Override
+    public void rsv1(boolean value) {
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading rsv1: {0}", value);
+        }
+        if (value) {
+            throw new FailWebSocketException("Unexpected rsv1 bit");
+        }
+    }
+
+    @Override
+    public void rsv2(boolean value) {
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading rsv2: {0}", value);
+        }
+        if (value) {
+            throw new FailWebSocketException("Unexpected rsv2 bit");
+        }
+    }
+
+    @Override
+    public void rsv3(boolean value) {
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading rsv3: {0}", value);
+        }
+        if (value) {
+            throw new FailWebSocketException("Unexpected rsv3 bit");
+        }
+    }
+
+    @Override
+    public void opcode(Opcode v) {
+        logger.log(TRACE, "Reading opcode: {0}", v);
+        if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
+            if (!fin) {
+                throw new FailWebSocketException("Fragmented control frame  " + v);
+            }
+            opcode = v;
+        } else if (v == Opcode.TEXT || v == Opcode.BINARY) {
+            if (originatingOpcode != null) {
+                throw new FailWebSocketException(
+                        format("Unexpected frame %s (fin=%s)", v, fin));
+            }
+            opcode = v;
+            if (!fin) {
+                originatingOpcode = v;
+            }
+        } else if (v == Opcode.CONTINUATION) {
+            if (originatingOpcode == null) {
+                throw new FailWebSocketException(
+                        format("Unexpected frame %s (fin=%s)", v, fin));
+            }
+            opcode = v;
+        } else {
+            throw new FailWebSocketException("Unknown opcode " + v);
+        }
+    }
+
+    @Override
+    public void mask(boolean value) {
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading mask: {0}", value);
+        }
+        if (value) {
+            throw new FailWebSocketException("Masked frame received");
+        }
+    }
+
+    @Override
+    public void payloadLen(long value) {
+        if (logger.isLoggable(TRACE)) {
+            // Checked for being loggable because of autoboxing of 'value'
+            logger.log(TRACE, "Reading payloadLen: {0}", value);
+        }
+        if (opcode.isControl()) {
+            if (value > 125) {
+                throw new FailWebSocketException(
+                        format("%s's payload length %s", opcode, value));
+            }
+            assert Opcode.CLOSE.isControl();
+            if (opcode == Opcode.CLOSE && value == 1) {
+                throw new FailWebSocketException("Incomplete status code");
+            }
+        }
+        payloadLen = value;
+        unconsumedPayloadLen = value;
+    }
+
+    @Override
+    public void maskingKey(int value) {
+        // `FrameConsumer.mask(boolean)` is where a masked frame is detected and
+        // reported on; `FrameConsumer.mask(boolean)` MUST be invoked before
+        // this method;
+        // So this method (`maskingKey`) is not supposed to be invoked while
+        // reading a frame that has came from the server. If this method is
+        // invoked, then it's an error in implementation, thus InternalError
+        throw new InternalError();
+    }
+
+    @Override
+    public void payloadData(ByteBuffer data) {
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading payloadData: data={0}", data);
+        }
+        unconsumedPayloadLen -= data.remaining();
+        boolean isLast = unconsumedPayloadLen == 0;
+        if (opcode.isControl()) {
+            if (binaryData != null) { // An intermediate or the last chunk
+                binaryData.put(data);
+            } else if (!isLast) { // The first chunk
+                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);
+                binaryData = ByteBuffer.allocate(125).put(data);
+            } else { // The only chunk
+                binaryData = ByteBuffer.allocate(data.remaining()).put(data);
+            }
+        } else {
+            part = determinePart(isLast);
+            boolean text = opcode == Opcode.TEXT || originatingOpcode == Opcode.TEXT;
+            if (!text) {
+                output.onBinary(part, data.slice());
+                data.position(data.limit()); // Consume
+            } else {
+                boolean binaryNonEmpty = data.hasRemaining();
+                CharBuffer textData;
+                try {
+                    textData = decoder.decode(data, part == MessagePart.WHOLE || part == MessagePart.LAST);
+                } catch (CharacterCodingException e) {
+                    throw new FailWebSocketException(
+                            "Invalid UTF-8 in frame " + opcode, StatusCodes.NOT_CONSISTENT)
+                            .initCause(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, textData);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void endFrame() {
+        if (opcode.isControl()) {
+            binaryData.flip();
+        }
+        switch (opcode) {
+            case CLOSE:
+                int statusCode = NO_STATUS_CODE;
+                String reason = "";
+                if (payloadLen != 0) {
+                    int len = binaryData.remaining();
+                    assert 2 <= len && len <= 125 : dump(len, payloadLen);
+                    try {
+                        statusCode = checkIncomingCode(binaryData.getChar());
+                        reason = UTF_8.newDecoder().decode(binaryData).toString();
+                    } catch (CheckFailedException e) {
+                        throw new FailWebSocketException("Incorrect status code")
+                                .initCause(e);
+                    } catch (CharacterCodingException e) {
+                        throw new FailWebSocketException(
+                                "Close reason is a malformed UTF-8 sequence")
+                                .initCause(e);
+                    }
+                }
+                output.onClose(statusCode, 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/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/MessageStreamConsumer.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.WebSocket.MessagePart;
+
+import java.nio.ByteBuffer;
+
+/*
+ * A callback for consuming messages and related events on the stream.
+ */
+interface MessageStreamConsumer {
+
+    void onText(MessagePart part, CharSequence data);
+
+    void onBinary(MessagePart part, ByteBuffer data);
+
+    void onPing(ByteBuffer data);
+
+    void onPong(ByteBuffer data);
+
+    void onClose(int statusCode, CharSequence reason);
+
+    void onError(Exception e);
+
+    /*
+     * Indicates the end of stream has been reached and there will be no further
+     * messages.
+     */
+    void onComplete();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/OpeningHandshake.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.internal.common.MinimalFuture;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpClient.Version;
+import jdk.incubator.http.HttpHeaders;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import jdk.incubator.http.HttpResponse.BodyHandler;
+import jdk.incubator.http.WebSocketHandshakeException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.time.Duration;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static jdk.incubator.http.internal.common.Utils.isValidName;
+import static jdk.incubator.http.internal.common.Utils.stringOf;
+
+final class OpeningHandshake {
+
+    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 Set<String> FORBIDDEN_HEADERS;
+
+    static {
+        FORBIDDEN_HEADERS = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FORBIDDEN_HEADERS.addAll(List.of(HEADER_ACCEPT,
+                                         HEADER_EXTENSIONS,
+                                         HEADER_KEY,
+                                         HEADER_PROTOCOL,
+                                         HEADER_VERSION));
+    }
+
+    private static final SecureRandom srandom = new SecureRandom();
+
+    private final MessageDigest sha1;
+    private final HttpClient client;
+
+    {
+        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 requirements", e);
+        }
+    }
+
+    private final HttpRequest request;
+    private final Collection<String> subprotocols;
+    private final String nonce;
+
+    OpeningHandshake(BuilderImpl b) {
+        this.client = b.getClient();
+        URI httpURI = createRequestURI(b.getUri());
+        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(httpURI);
+        Duration connectTimeout = b.getConnectTimeout();
+        if (connectTimeout != null) {
+            requestBuilder.timeout(connectTimeout);
+        }
+        this.subprotocols = createRequestSubprotocols(b.getSubprotocols());
+        if (!this.subprotocols.isEmpty()) {
+            String p = this.subprotocols.stream().collect(Collectors.joining(", "));
+            requestBuilder.header(HEADER_PROTOCOL, p);
+        }
+        requestBuilder.header(HEADER_VERSION, VALUE_VERSION);
+        this.nonce = createNonce();
+        requestBuilder.header(HEADER_KEY, this.nonce);
+        // Setting request version to HTTP/1.1 forcibly, since it's not possible
+        // to upgrade from HTTP/2 to WebSocket (as of August 2016):
+        //
+        //     https://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-00
+        this.request = requestBuilder.version(Version.HTTP_1_1).GET().build();
+        WebSocketRequest r = (WebSocketRequest) this.request;
+        r.isWebSocket(true);
+        r.setSystemHeader(HEADER_UPGRADE, "websocket");
+        r.setSystemHeader(HEADER_CONNECTION, "Upgrade");
+    }
+
+    private static Collection<String> createRequestSubprotocols(
+            Collection<String> subprotocols)
+    {
+        LinkedHashSet<String> sp = new LinkedHashSet<>(subprotocols.size(), 1);
+        for (String s : subprotocols) {
+            if (s.trim().isEmpty() || !isValidName(s)) {
+                throw illegal("Bad subprotocol syntax: " + s);
+            }
+            if (FORBIDDEN_HEADERS.contains(s)) {
+                throw illegal("Forbidden header: " + s);
+            }
+            boolean unique = sp.add(s);
+            if (!unique) {
+                throw illegal("Duplicating subprotocol: " + s);
+            }
+        }
+        return Collections.unmodifiableCollection(sp);
+    }
+
+    /*
+     * Checks the given URI for being a WebSocket URI and translates it into a
+     * target HTTP URI for the Opening Handshake.
+     *
+     * https://tools.ietf.org/html/rfc6455#section-3
+     */
+    private static URI createRequestURI(URI uri) {
+        // TODO: check permission for WebSocket URI and translate it into
+        // http/https permission
+        String s = uri.getScheme(); // The scheme might be null (i.e. undefined)
+        if (!("ws".equalsIgnoreCase(s) || "wss".equalsIgnoreCase(s))
+                || uri.getFragment() != null)
+        {
+            throw illegal("Bad URI: " + uri);
+        }
+        String scheme = "ws".equalsIgnoreCase(s) ? "http" : "https";
+        try {
+            return new URI(scheme,
+                           uri.getUserInfo(),
+                           uri.getHost(),
+                           uri.getPort(),
+                           uri.getPath(),
+                           uri.getQuery(),
+                           null); // No fragment
+        } catch (URISyntaxException e) {
+            // Shouldn't happen: URI invariant
+            throw new InternalError(e);
+        }
+    }
+
+    CompletableFuture<Result> send() {
+        return client.sendAsync(this.request, BodyHandler.<Void>discard(null))
+                     .thenCompose(this::resultFrom);
+    }
+
+    /*
+     * The result of the opening handshake.
+     */
+    static final class Result {
+
+        final String subprotocol;
+        final RawChannel channel;
+
+        private Result(String subprotocol, RawChannel channel) {
+            this.subprotocol = subprotocol;
+            this.channel = channel;
+        }
+    }
+
+    private CompletableFuture<Result> resultFrom(HttpResponse<?> response) {
+        // Do we need a special treatment for SSLHandshakeException?
+        // Namely, invoking
+        //
+        //     Listener.onClose(StatusCodes.TLS_HANDSHAKE_FAILURE, "")
+        //
+        // See https://tools.ietf.org/html/rfc6455#section-7.4.1
+        Result result = null;
+        Exception exception = null;
+        try {
+            result = handleResponse(response);
+        } catch (IOException e) {
+            exception = e;
+        } catch (Exception e) {
+            exception = new WebSocketHandshakeException(response).initCause(e);
+        }
+        if (exception == null) {
+            return MinimalFuture.completedFuture(result);
+        }
+        try {
+            ((RawChannel.Provider) response).rawChannel().close();
+        } catch (IOException e) {
+            exception.addSuppressed(e);
+        }
+        return MinimalFuture.failedFuture(exception);
+    }
+
+    private Result handleResponse(HttpResponse<?> response) throws IOException {
+        // 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 c = response.statusCode();
+        if (c != 101) {
+            throw checkFailed("Unexpected HTTP response status code " + c);
+        }
+        HttpHeaders headers = response.headers();
+        String upgrade = requireSingle(headers, HEADER_UPGRADE);
+        if (!upgrade.equalsIgnoreCase("websocket")) {
+            throw checkFailed("Bad response field: " + HEADER_UPGRADE);
+        }
+        String connection = requireSingle(headers, HEADER_CONNECTION);
+        if (!connection.equalsIgnoreCase("Upgrade")) {
+            throw checkFailed("Bad response field: " + HEADER_CONNECTION);
+        }
+        requireAbsent(headers, HEADER_VERSION);
+        requireAbsent(headers, HEADER_EXTENSIONS);
+        String x = this.nonce + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+        this.sha1.update(x.getBytes(StandardCharsets.ISO_8859_1));
+        String expected = Base64.getEncoder().encodeToString(this.sha1.digest());
+        String actual = requireSingle(headers, HEADER_ACCEPT);
+        if (!actual.trim().equals(expected)) {
+            throw checkFailed("Bad " + HEADER_ACCEPT);
+        }
+        String subprotocol = checkAndReturnSubprotocol(headers);
+        RawChannel channel = ((RawChannel.Provider) response).rawChannel();
+        return new Result(subprotocol, channel);
+    }
+
+    private String checkAndReturnSubprotocol(HttpHeaders responseHeaders)
+            throws CheckFailedException
+    {
+        Optional<String> opt = responseHeaders.firstValue(HEADER_PROTOCOL);
+        if (!opt.isPresent()) {
+            // If there is no such header in the response, then the server
+            // doesn't want to use any subprotocol
+            return "";
+        }
+        String s = requireSingle(responseHeaders, HEADER_PROTOCOL);
+        // An empty string as a subprotocol's name is not allowed by the spec
+        // and the check below will detect such responses too
+        if (this.subprotocols.contains(s)) {
+            return s;
+        } else {
+            throw checkFailed("Unexpected subprotocol: " + s);
+        }
+    }
+
+    private static void requireAbsent(HttpHeaders responseHeaders,
+                                      String headerName)
+    {
+        List<String> values = responseHeaders.allValues(headerName);
+        if (!values.isEmpty()) {
+            throw checkFailed(format("Response field '%s' present: %s",
+                                     headerName,
+                                     stringOf(values)));
+        }
+    }
+
+    private static String requireSingle(HttpHeaders responseHeaders,
+                                        String headerName)
+            throws CheckFailedException
+    {
+        List<String> values = responseHeaders.allValues(headerName);
+        if (values.isEmpty()) {
+            throw checkFailed("Response field missing: " + headerName);
+        } else if (values.size() > 1) {
+            throw checkFailed(format("Response field '%s' multivalued: %s",
+                                     headerName,
+                                     stringOf(values)));
+        }
+        return values.get(0);
+    }
+
+    private static String createNonce() {
+        byte[] bytes = new byte[16];
+        OpeningHandshake.srandom.nextBytes(bytes);
+        return Base64.getEncoder().encodeToString(bytes);
+    }
+
+    private static IllegalArgumentException illegal(String message) {
+        return new IllegalArgumentException(message);
+    }
+
+    private static CheckFailedException checkFailed(String message) {
+        throw new CheckFailedException(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/OutgoingMessage.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.security.SecureRandom;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Objects.requireNonNull;
+import static jdk.incubator.http.internal.common.Utils.EMPTY_BYTEBUFFER;
+import static jdk.incubator.http.internal.websocket.Frame.MAX_HEADER_SIZE_BYTES;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.BINARY;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.CLOSE;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.CONTINUATION;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.PING;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.PONG;
+import static jdk.incubator.http.internal.websocket.Frame.Opcode.TEXT;
+
+/*
+ * A stateful object that represents a WebSocket message being sent to the
+ * channel.
+ *
+ * Data provided to the constructors is copied. Otherwise we would have to deal
+ * with mutability, security, masking/unmasking, readonly status, etc. So
+ * copying greatly simplifies the implementation.
+ *
+ * In the case of memory-sensitive environments an alternative implementation
+ * could use an internal pool of buffers though at the cost of extra complexity
+ * and possible performance degradation.
+ */
+abstract class OutgoingMessage {
+
+    private static final SecureRandom maskingKeys = new SecureRandom();
+
+    protected ByteBuffer[] frame;
+    protected int offset;
+
+    /*
+     * Performs contextualization. This method is not a part of the constructor
+     * so it would be possible to defer the work it does until the most
+     * convenient moment (up to the point where sentTo is invoked).
+     */
+    protected void contextualize(Context context) {
+        if (context.isCloseSent()) {
+            throw new IllegalStateException("Close sent");
+        }
+    }
+
+    protected boolean sendTo(RawChannel channel) throws IOException {
+        while ((offset = nextUnwrittenIndex()) != -1) {
+            long n = channel.write(frame, offset, frame.length - offset);
+            if (n == 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private int nextUnwrittenIndex() {
+        for (int i = offset; i < frame.length; i++) {
+            if (frame[i].hasRemaining()) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    static final class Text extends OutgoingMessage {
+
+        private final ByteBuffer payload;
+        private final boolean isLast;
+
+        Text(CharSequence characters, boolean isLast) {
+            CharsetEncoder encoder = UTF_8.newEncoder();
+            try {
+                payload = encoder.encode(CharBuffer.wrap(characters));
+            } catch (CharacterCodingException e) {
+                throw new IllegalArgumentException(
+                        "Malformed UTF-8 text message");
+            }
+            this.isLast = isLast;
+        }
+
+        @Override
+        protected void contextualize(Context context) {
+            super.contextualize(context);
+            if (context.isPreviousBinary() && !context.isPreviousLast()) {
+                throw new IllegalStateException("Unexpected text message");
+            }
+            frame = getDataMessageBuffers(
+                    TEXT, context.isPreviousLast(), isLast, payload, payload);
+            context.setPreviousBinary(false);
+            context.setPreviousText(true);
+            context.setPreviousLast(isLast);
+        }
+    }
+
+    static final class Binary extends OutgoingMessage {
+
+        private final ByteBuffer payload;
+        private final boolean isLast;
+
+        Binary(ByteBuffer payload, boolean isLast) {
+            this.payload = requireNonNull(payload);
+            this.isLast = isLast;
+        }
+
+        @Override
+        protected void contextualize(Context context) {
+            super.contextualize(context);
+            if (context.isPreviousText() && !context.isPreviousLast()) {
+                throw new IllegalStateException("Unexpected binary message");
+            }
+            ByteBuffer newBuffer = ByteBuffer.allocate(payload.remaining());
+            frame = getDataMessageBuffers(
+                    BINARY, context.isPreviousLast(), isLast, payload, newBuffer);
+            context.setPreviousText(false);
+            context.setPreviousBinary(true);
+            context.setPreviousLast(isLast);
+        }
+    }
+
+    static final class Ping extends OutgoingMessage {
+
+        Ping(ByteBuffer payload) {
+            frame = getControlMessageBuffers(PING, payload);
+        }
+    }
+
+    static final class Pong extends OutgoingMessage {
+
+        Pong(ByteBuffer payload) {
+            frame = getControlMessageBuffers(PONG, payload);
+        }
+    }
+
+    static final class Close extends OutgoingMessage {
+
+        Close() {
+            frame = getControlMessageBuffers(CLOSE, EMPTY_BYTEBUFFER);
+        }
+
+        Close(int statusCode, CharSequence reason) {
+            ByteBuffer payload = ByteBuffer.allocate(125)
+                                           .putChar((char) statusCode);
+            CoderResult result = UTF_8.newEncoder()
+                                      .encode(CharBuffer.wrap(reason),
+                                              payload,
+                                              true);
+            if (result.isOverflow()) {
+                throw new IllegalArgumentException("Long reason");
+            } else if (result.isError()) {
+                try {
+                    result.throwException();
+                } catch (CharacterCodingException e) {
+                    throw new IllegalArgumentException(
+                            "Malformed UTF-8 reason", e);
+                }
+            }
+            payload.flip();
+            frame = getControlMessageBuffers(CLOSE, payload);
+        }
+
+        @Override
+        protected void contextualize(Context context) {
+            super.contextualize(context);
+            context.setCloseSent();
+        }
+    }
+
+    private static ByteBuffer[] getControlMessageBuffers(Opcode opcode,
+                                                         ByteBuffer payload) {
+        assert opcode.isControl() : opcode;
+        int remaining = payload.remaining();
+        if (remaining > 125) {
+            throw new IllegalArgumentException
+                    ("Long message: " + remaining);
+        }
+        ByteBuffer frame = ByteBuffer.allocate(MAX_HEADER_SIZE_BYTES + remaining);
+        int mask = maskingKeys.nextInt();
+        new Frame.HeaderWriter()
+                .fin(true)
+                .opcode(opcode)
+                .payloadLen(remaining)
+                .mask(mask)
+                .write(frame);
+        Frame.Masker.transferMasking(payload, frame, mask);
+        frame.flip();
+        return new ByteBuffer[]{frame};
+    }
+
+    private static ByteBuffer[] getDataMessageBuffers(Opcode type,
+                                                      boolean isPreviousLast,
+                                                      boolean isLast,
+                                                      ByteBuffer payloadSrc,
+                                                      ByteBuffer payloadDst) {
+        assert !type.isControl() && type != CONTINUATION : type;
+        ByteBuffer header = ByteBuffer.allocate(MAX_HEADER_SIZE_BYTES);
+        int mask = maskingKeys.nextInt();
+        new Frame.HeaderWriter()
+                .fin(isLast)
+                .opcode(isPreviousLast ? type : CONTINUATION)
+                .payloadLen(payloadDst.remaining())
+                .mask(mask)
+                .write(header);
+        header.flip();
+        Frame.Masker.transferMasking(payloadSrc, payloadDst, mask);
+        payloadDst.flip();
+        return new ByteBuffer[]{header, payloadDst};
+    }
+
+    /*
+     * An instance of this class is passed sequentially between messages, so
+     * every message in a sequence can check the context it is in and update it
+     * if necessary.
+     */
+    public static class Context {
+
+        boolean previousLast = true;
+        boolean previousBinary;
+        boolean previousText;
+        boolean closeSent;
+
+        private boolean isPreviousText() {
+            return this.previousText;
+        }
+
+        private void setPreviousText(boolean value) {
+            this.previousText = value;
+        }
+
+        private boolean isPreviousBinary() {
+            return this.previousBinary;
+        }
+
+        private void setPreviousBinary(boolean value) {
+            this.previousBinary = value;
+        }
+
+        private boolean isPreviousLast() {
+            return this.previousLast;
+        }
+
+        private void setPreviousLast(boolean value) {
+            this.previousLast = value;
+        }
+
+        private boolean isCloseSent() {
+            return closeSent;
+        }
+
+        private void setCloseSent() {
+            closeSent = true;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/RawChannel.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+
+/*
+ * I/O abstraction used to implement WebSocket.
+ *
+ * @since 9
+ */
+public interface RawChannel extends Closeable {
+
+    interface Provider {
+
+        RawChannel rawChannel() throws IOException;
+    }
+
+    interface RawEvent {
+
+        /*
+         * Returns the selector op flags this event is interested in.
+         */
+        int interestOps();
+
+        /*
+         * Called when event occurs.
+         */
+        void handle();
+    }
+
+    /*
+     * Registers given event whose callback will be called once only (i.e.
+     * register new event for each callback).
+     *
+     * Memory consistency effects: actions in a thread calling registerEvent
+     * happen-before any subsequent actions in the thread calling event.handle
+     */
+    void registerEvent(RawEvent event) throws IOException;
+
+    /**
+     * Hands over the initial bytes. Once the bytes have been returned they are
+     * no longer available and the method will throw an {@link
+     * IllegalStateException} on each subsequent invocation.
+     *
+     * @return the initial bytes
+     * @throws IllegalStateException
+     *         if the method has been already invoked
+     */
+    ByteBuffer initialByteBuffer() throws IllegalStateException;
+
+    /*
+     * Returns a ByteBuffer with the data read or null if EOF is reached. Has no
+     * remaining bytes if no data available at the moment.
+     */
+    ByteBuffer read() throws IOException;
+
+    /*
+     * Writes a sequence of bytes to this channel from a subsequence of the
+     * given buffers.
+     */
+    long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
+
+    /**
+     * Shutdown the connection for reading without closing the channel.
+     *
+     * <p> Once shutdown for reading then further reads on the channel will
+     * return {@code null}, the end-of-stream indication. If the input side of
+     * the connection is already shutdown then invoking this method has no
+     * effect.
+     *
+     * @throws ClosedChannelException
+     *         If this channel is closed
+     * @throws IOException
+     *         If some other I/O error occurs
+     */
+    void shutdownInput() throws IOException;
+
+    /**
+     * Shutdown the connection for writing without closing the channel.
+     *
+     * <p> Once shutdown for writing then further attempts to write to the
+     * channel will throw {@link ClosedChannelException}. If the output side of
+     * the connection is already shutdown then invoking this method has no
+     * effect.
+     *
+     * @throws ClosedChannelException
+     *         If this channel is closed
+     * @throws IOException
+     *         If some other I/O error occurs
+     */
+    void shutdownOutput() throws IOException;
+
+    /**
+     * Closes this channel.
+     *
+     * @throws IOException
+     *         If an I/O error occurs
+     */
+    @Override
+    void close() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/Receiver.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http.internal.websocket;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+/*
+ * Receives incoming data from the channel on demand and converts it into a
+ * stream of WebSocket messages which are then delivered to the supplied message
+ * consumer in a strict sequential order and non-recursively. In other words,
+ *
+ *     onText()
+ *     onText()
+ *     onBinary()
+ *     ...
+ *
+ * instead of
+ *
+ *     onText()
+ *       onText()
+ *         onBinary()
+ *     ...
+ *
+ * even if `request(long n)` is called from inside these invocations.
+ */
+final class Receiver {
+
+    private final MessageStreamConsumer messageConsumer;
+    private final RawChannel channel;
+    private final FrameConsumer frameConsumer;
+    private final Frame.Reader reader = new Frame.Reader();
+    private final RawChannel.RawEvent event = createHandler();
+    private final AtomicLong demand = new AtomicLong();
+    private final CooperativeHandler receiveHandler =
+              new CooperativeHandler(this::tryDeliver);
+    /*
+     * Used to ensure registering the channel event at most once (i.e. to avoid
+     * multiple registrations).
+     */
+    private final AtomicBoolean readable = new AtomicBoolean();
+    private ByteBuffer data;
+
+    Receiver(MessageStreamConsumer messageConsumer, RawChannel channel) {
+        this.messageConsumer = messageConsumer;
+        this.channel = channel;
+        this.data = channel.initialByteBuffer();
+        this.frameConsumer = new FrameConsumer(this.messageConsumer);
+        // To ensure the initial `data` will be read correctly (happens-before)
+        // after readable.get()
+        readable.set(true);
+    }
+
+    private RawChannel.RawEvent createHandler() {
+        return new RawChannel.RawEvent() {
+
+            @Override
+            public int interestOps() {
+                return SelectionKey.OP_READ;
+            }
+
+            @Override
+            public void handle() {
+                readable.set(true);
+                receiveHandler.startOrContinue();
+            }
+        };
+    }
+
+    void request(long n) {
+        if (n < 0L) {
+            throw new IllegalArgumentException("Negative: " + n);
+        }
+        demand.accumulateAndGet(n, (p, i) -> p + i < 0 ? Long.MAX_VALUE : p + i);
+        receiveHandler.startOrContinue();
+    }
+
+    void acknowledge() {
+        long x = demand.decrementAndGet();
+        if (x < 0) {
+            throw new InternalError(String.valueOf(x));
+        }
+    }
+
+    /*
+     * Stops the machinery from reading and delivering messages permanently,
+     * regardless of the current demand.
+     */
+    void close() {
+        receiveHandler.stop();
+    }
+
+    private void tryDeliver() {
+        if (readable.get() && demand.get() > 0) {
+            deliverAtMostOne();
+        }
+    }
+
+    private void deliverAtMostOne() {
+        if (data == null) {
+            try {
+                data = channel.read();
+            } catch (IOException e) {
+                readable.set(false);
+                messageConsumer.onError(e);
+                return;
+            }
+            if (data == null || !data.hasRemaining()) {
+                readable.set(false);
+                if (!data.hasRemaining()) {
+                    try {
+                        channel.registerEvent(event);
+                    } catch (IOException e) {
+                        messageConsumer.onError(e);
+                        return;
+                    }
+                } else if (data == null) {
+                    messageConsumer.onComplete();
+                }
+                return;
+            }
+        }
+        try {
+            reader.readFrame(data, frameConsumer);
+        } catch (FailWebSocketException e) {
+            messageConsumer.onError(e);
+            return;
+        }
+        if (!data.hasRemaining()) {
+            data = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/StatusCodes.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import static jdk.incubator.http.WebSocket.CLOSED_ABNORMALLY;
+
+/*
+ * Utilities and common constants for WebSocket status codes. For more details
+ * on status codes and their meaning see:
+ *
+ *     1. https://tools.ietf.org/html/rfc6455#section-7.4
+ *     2. http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
+ */
+final class StatusCodes {
+
+    static final int PROTOCOL_ERROR        = 1002;
+    static final int CANNOT_ACCEPT         = 1003;
+    static final int NO_STATUS_CODE        = 1005;
+    static final int NOT_CONSISTENT        = 1007;
+    static final int TOO_BIG               = 1009;
+    static final int NO_EXTENSION          = 1010;
+    static final int SERVICE_RESTART       = 1012;
+    static final int TRY_AGAIN_LATER       = 1013;
+    static final int TLS_HANDSHAKE_FAILURE = 1015;
+
+    private StatusCodes() { }
+
+    /*
+     * Returns the given code if it doesn't violate any rules for outgoing
+     * codes, otherwise throws a CFE with a detailed description.
+     */
+    static int checkOutgoingCode(int code) {
+        checkCommon(code);
+        if (code > 4999) {
+            throw new CheckFailedException("Unspecified: " + code);
+        }
+        if (isNotUserSettable(code)) {
+            throw new CheckFailedException("Cannot set: " + code);
+        }
+        return code;
+    }
+
+    /*
+     * Returns the given code if it doesn't violate any rules for incoming
+     * codes, otherwise throws a CFE with a detailed description.
+     */
+    static int checkIncomingCode(int code) {
+        checkCommon(code);
+        if (code == NO_EXTENSION) {
+            throw new CheckFailedException("Bad server code: " + code);
+        }
+        return code;
+    }
+
+    private static int checkCommon(int code) {
+        if (isOutOfRange(code)) {
+            throw new CheckFailedException("Out of range: " + code);
+        }
+        if (isForbidden(code)) {
+            throw new CheckFailedException("Forbidden: " + code);
+        }
+        if (isUnassigned(code)) {
+            throw new CheckFailedException("Unassigned: " + code);
+        }
+        return code;
+    }
+
+    /*
+     * Returns true if the given code cannot be set by a user of the WebSocket
+     * API. e.g. this code means something which only a WebSocket implementation
+     * is responsible for or it doesn't make sense to be send by a WebSocket
+     * client.
+     */
+    private static boolean isNotUserSettable(int code) {
+        switch (code) {
+            case PROTOCOL_ERROR:
+            case CANNOT_ACCEPT:
+            case NOT_CONSISTENT:
+            case TOO_BIG:
+            case NO_EXTENSION:
+            case TRY_AGAIN_LATER:
+            case SERVICE_RESTART:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /*
+     * Returns true if the given code cannot appear on the wire. It's always an
+     * error to send a frame with such a code or to receive one.
+     */
+    private static boolean isForbidden(int code) {
+        switch (code) {
+            case NO_STATUS_CODE:
+            case CLOSED_ABNORMALLY:
+            case TLS_HANDSHAKE_FAILURE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /*
+     * Returns true if the given code has no known meaning under the WebSocket
+     * specification (i.e. unassigned/undefined).
+     */
+    private static boolean isUnassigned(int code) {
+        return (code >= 1016 && code <= 2999) || code == 1004 || code == 1014;
+    }
+
+    /*
+     * Returns true if the given code is not in domain of status codes:
+     *
+     * 2-byte unsigned integer minus first 1000 numbers from the range [0, 999]
+     * that are never used.
+     */
+    private static boolean isOutOfRange(int code) {
+        return code < 1000 || code > 65535;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/Transmitter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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.  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.incubator.http.internal.websocket;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
+import static java.util.Objects.requireNonNull;
+
+/*
+ * Sends messages one at a time, in an asynchronous and non-blocking fashion.
+ *
+ * No matter whether the message has been fully sent or an error has occurred,
+ * the transmitter reports the outcome to the supplied handler and becomes ready
+ * to accept a new message. Until then, it is considered "busy" and an
+ * IllegalStateException will be thrown on each attempt to invoke send.
+ */
+final class Transmitter {
+
+    private final AtomicBoolean busy = new AtomicBoolean();
+    private OutgoingMessage message;
+    private Consumer<Exception> completionHandler;
+    private final RawChannel channel;
+    private final RawChannel.RawEvent event;
+
+    Transmitter(RawChannel channel) {
+        this.channel = requireNonNull(channel);
+        this.event = createHandler();
+    }
+
+    /*
+     * The supplied handler may be invoked in the calling thread, so watch out
+     * for stack overflow.
+     */
+    void send(OutgoingMessage message, Consumer<Exception> completionHandler) {
+        requireNonNull(message);
+        requireNonNull(completionHandler);
+        if (!busy.compareAndSet(false, true)) {
+            throw new IllegalStateException();
+        }
+        send0(message, completionHandler);
+    }
+
+    private RawChannel.RawEvent createHandler() {
+        return new RawChannel.RawEvent() {
+
+            @Override
+            public int interestOps() {
+                return SelectionKey.OP_WRITE;
+            }
+
+            @Override
+            public void handle() {
+                // registerEvent(e) happens-before subsequent e.handle(), so
+                // we're fine reading the stored message and the completionHandler
+                send0(message, completionHandler);
+            }
+        };
+    }
+
+    private void send0(OutgoingMessage message, Consumer<Exception> handler) {
+        boolean b = busy.get();
+        assert b; // Please don't inline this, as busy.get() has memory
+                  // visibility effects and we don't want the correctness
+                  // of the algorithm to depend on assertions flag
+        try {
+            boolean sent = message.sendTo(channel);
+            if (sent) {
+                busy.set(false);
+                handler.accept(null);
+            } else {
+                // The message has not been fully sent, the transmitter needs to
+                // remember the message until it can continue with sending it
+                this.message = message;
+                this.completionHandler = handler;
+                try {
+                    channel.registerEvent(event);
+                } catch (IOException e) {
+                    this.message = null;
+                    this.completionHandler = null;
+                    busy.set(false);
+                    handler.accept(e);
+                }
+            }
+        } catch (IOException e) {
+            busy.set(false);
+            handler.accept(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/UTF8AccumulatingDecoder.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+import static java.lang.System.Logger.Level.WARNING;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static jdk.incubator.http.internal.common.Utils.EMPTY_BYTEBUFFER;
+import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
+
+final class UTF8AccumulatingDecoder {
+
+    private final CharsetDecoder decoder = UTF_8.newDecoder();
+
+    {
+        decoder.onMalformedInput(CodingErrorAction.REPORT);
+        decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+    }
+
+    private ByteBuffer leftovers = EMPTY_BYTEBUFFER;
+
+    CharBuffer decode(ByteBuffer in, boolean endOfInput)
+            throws CharacterCodingException
+    {
+        ByteBuffer b;
+        int rem = leftovers.remaining();
+        if (rem != 0) {
+            // 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).flip();
+        } else {
+            b = in;
+        }
+        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_BYTEBUFFER;
+        }
+        // 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
+        // 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");
+            }
+        }
+        return out.flip();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketImpl.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.WebSocket;
+import jdk.incubator.http.internal.common.Pair;
+import jdk.incubator.http.internal.websocket.OpeningHandshake.Result;
+import jdk.incubator.http.internal.websocket.OutgoingMessage.Binary;
+import jdk.incubator.http.internal.websocket.OutgoingMessage.Close;
+import jdk.incubator.http.internal.websocket.OutgoingMessage.Context;
+import jdk.incubator.http.internal.websocket.OutgoingMessage.Ping;
+import jdk.incubator.http.internal.websocket.OutgoingMessage.Pong;
+import jdk.incubator.http.internal.websocket.OutgoingMessage.Text;
+
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.TRACE;
+import static java.util.Objects.requireNonNull;
+import static java.util.concurrent.CompletableFuture.failedFuture;
+import static jdk.incubator.http.internal.common.Pair.pair;
+import static jdk.incubator.http.internal.websocket.StatusCodes.NO_STATUS_CODE;
+import static jdk.incubator.http.internal.websocket.StatusCodes.TLS_HANDSHAKE_FAILURE;
+import static jdk.incubator.http.internal.websocket.StatusCodes.checkOutgoingCode;
+
+/*
+ * A WebSocket client.
+ */
+final class WebSocketImpl implements WebSocket {
+
+    static final System.Logger logger = System.getLogger("jdk.httpclient.WebSocket");
+
+    private final URI uri;
+    private final String subprotocol;
+    private final RawChannel channel;
+    private final Listener listener;
+
+    /*
+     * Whether or not Listener.onClose or Listener.onError has been already
+     * invoked. We keep track of this since only one of these methods is invoked
+     * and it is invoked at most once.
+     */
+    private boolean lastMethodInvoked;
+    private final AtomicBoolean outstandingSend = new AtomicBoolean();
+    private final CooperativeHandler sendHandler =
+              new CooperativeHandler(this::sendFirst);
+    private final Queue<Pair<OutgoingMessage, Consumer<Exception>>> queue =
+              new ConcurrentLinkedQueue<>();
+    private final Context context = new OutgoingMessage.Context();
+    private final Transmitter transmitter;
+    private final Receiver receiver;
+
+    /*
+     * Whether or not the WebSocket has been closed. When a WebSocket has been
+     * closed it means that no further messages can be sent or received.
+     * A closure can be triggered by:
+     *
+     *   1. abort()
+     *   2. "Failing the WebSocket Connection" (i.e. a fatal error)
+     *   3. Completion of the Closing handshake
+     */
+    private final AtomicBoolean closed = new AtomicBoolean();
+
+    /*
+     * This lock is enforcing sequential ordering of invocations to listener's
+     * methods. It is supposed to be uncontended. The only contention that can
+     * happen is when onOpen, an asynchronous onError (not related to reading
+     * from the channel, e.g. an error from automatic Pong reply) or onClose
+     * (related to abort) happens. Since all of the above are one-shot actions,
+     * the said contention is insignificant.
+     */
+    private final Object lock = new Object();
+
+    private final CompletableFuture<?> closeReceived = new CompletableFuture<>();
+    private final CompletableFuture<?> closeSent = new CompletableFuture<>();
+
+    static CompletableFuture<WebSocket> newInstanceAsync(BuilderImpl b) {
+        Function<Result, WebSocket> newWebSocket = r -> {
+            WebSocketImpl ws = new WebSocketImpl(b.getUri(),
+                                                 r.subprotocol,
+                                                 r.channel,
+                                                 b.getListener());
+            ws.signalOpen();
+            return ws;
+        };
+        OpeningHandshake h;
+        try {
+            h = new OpeningHandshake(b);
+        } catch (IllegalArgumentException e) {
+            return failedFuture(e);
+        }
+        return h.send().thenApply(newWebSocket);
+    }
+
+    WebSocketImpl(URI uri,
+                  String subprotocol,
+                  RawChannel channel,
+                  Listener listener) {
+        this.uri = requireNonNull(uri);
+        this.subprotocol = requireNonNull(subprotocol);
+        this.channel = requireNonNull(channel);
+        this.listener = requireNonNull(listener);
+        this.transmitter = new Transmitter(channel);
+        this.receiver = new Receiver(messageConsumerOf(listener), channel);
+
+        // Set up the Closing Handshake action
+        CompletableFuture.allOf(closeReceived, closeSent)
+                .whenComplete((result, error) -> {
+                    try {
+                        channel.close();
+                    } catch (IOException e) {
+                        logger.log(ERROR, e);
+                    } finally {
+                        closed.set(true);
+                    }
+                });
+    }
+
+    /*
+     * This initialisation is outside of the constructor for the sake of
+     * safe publication.
+     */
+    private void signalOpen() {
+        synchronized (lock) {
+            // TODO: might hold lock longer than needed causing prolonged
+            // contention? substitute lock for ConcurrentLinkedQueue<Runnable>?
+            try {
+                listener.onOpen(this);
+            } catch (Exception e) {
+                signalError(e);
+            }
+        }
+    }
+
+    private void signalError(Throwable error) {
+        synchronized (lock) {
+            if (lastMethodInvoked) {
+                logger.log(ERROR, error);
+            } else {
+                lastMethodInvoked = true;
+                receiver.close();
+                try {
+                    listener.onError(this, error);
+                } catch (Exception e) {
+                    logger.log(ERROR, e);
+                }
+            }
+        }
+    }
+
+    /*
+     * Processes a Close event that came from the channel. Invoked at most once.
+     */
+    private void processClose(int statusCode, String reason) {
+        assert statusCode != TLS_HANDSHAKE_FAILURE; // TLS problems happen long before WebSocket is alive
+        receiver.close();
+        try {
+            channel.shutdownInput();
+        } catch (IOException e) {
+            logger.log(ERROR, e);
+        }
+        boolean wasComplete = !closeReceived.complete(null);
+        if (wasComplete) {
+            throw new InternalError();
+        }
+        int code;
+        if (statusCode == NO_STATUS_CODE || statusCode == CLOSED_ABNORMALLY) {
+            code = NORMAL_CLOSURE;
+        } else {
+            code = statusCode;
+        }
+        CompletionStage<?> readyToClose = signalClose(statusCode, reason);
+        if (readyToClose == null) {
+            readyToClose = CompletableFuture.completedFuture(null);
+        }
+        readyToClose.whenComplete((r, error) -> {
+            enqueueClose(new Close(code, ""))
+                    .whenComplete((r1, error1) -> {
+                        if (error1 != null) {
+                            logger.log(ERROR, error1);
+                        }
+                    });
+        });
+    }
+
+    /*
+     * Signals a Close event (might not correspond to anything happened on the
+     * channel, e.g. `abort()`).
+     */
+    private CompletionStage<?> signalClose(int statusCode, String reason) {
+        synchronized (lock) {
+            if (lastMethodInvoked) {
+                logger.log(TRACE, "Close: {0}, ''{1}''", statusCode, reason);
+            } else {
+                lastMethodInvoked = true;
+                receiver.close();
+                try {
+                    return listener.onClose(this, statusCode, reason);
+                } catch (Exception e) {
+                    logger.log(ERROR, e);
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> sendText(CharSequence message,
+                                                 boolean isLast)
+    {
+        return enqueueExclusively(new Text(message, isLast));
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> sendBinary(ByteBuffer message,
+                                                   boolean isLast)
+    {
+        return enqueueExclusively(new Binary(message, isLast));
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
+        return enqueueExclusively(new Ping(message));
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
+        return enqueueExclusively(new Pong(message));
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> sendClose(int statusCode,
+                                                  String reason) {
+        try {
+            checkOutgoingCode(statusCode);
+        } catch (CheckFailedException e) {
+            IllegalArgumentException ex = new IllegalArgumentException(
+                    "Bad status code: " + statusCode, e);
+            failedFuture(ex);
+        }
+        return enqueueClose(new Close(statusCode, reason));
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> sendClose() {
+        return enqueueClose(new Close());
+    }
+
+    /*
+     * Sends a Close message with the given contents and then shuts down the
+     * channel for writing since no more messages are expected to be sent after
+     * this. Invoked at most once.
+     */
+    private CompletableFuture<WebSocket> enqueueClose(Close m) {
+        return enqueue(m).whenComplete((r, error) -> {
+            try {
+                channel.shutdownOutput();
+            } catch (IOException e) {
+                logger.log(ERROR, e);
+            }
+            boolean wasComplete = !closeSent.complete(null);
+            if (wasComplete) {
+                // Shouldn't happen as this callback must run at most once
+                throw new InternalError();
+            }
+        });
+    }
+
+    /*
+     * Accepts the given message into the outgoing queue in a mutually-exclusive
+     * fashion in respect to other messages accepted through this method. No
+     * further messages will be accepted until the returned CompletableFuture
+     * completes. This method is used to enforce "one outstanding send
+     * operation" policy.
+     */
+    private CompletableFuture<WebSocket> enqueueExclusively(OutgoingMessage m)
+    {
+        if (closed.get()) {
+            return failedFuture(new IllegalStateException("Closed"));
+        }
+        if (!outstandingSend.compareAndSet(false, true)) {
+            return failedFuture(new IllegalStateException("Outstanding send"));
+        }
+        return enqueue(m).whenComplete((r, e) -> outstandingSend.set(false));
+    }
+
+    private CompletableFuture<WebSocket> enqueue(OutgoingMessage m) {
+        CompletableFuture<WebSocket> cf = new CompletableFuture<>();
+        Consumer<Exception> h = e -> {
+            if (e == null) {
+                cf.complete(WebSocketImpl.this);
+                sendHandler.startOrContinue();
+            } else {
+
+//                what if this is not a users message? (must be different entry points for different messages)
+
+                // TODO: think about correct behaviour in the face of error in
+                // the queue, for now it seems like the best solution is to
+                // deliver the error and stop
+                cf.completeExceptionally(e);
+            }
+        };
+        queue.add(pair(m, h)); // Always returns true
+        sendHandler.startOrContinue();
+        return cf;
+    }
+
+    private void sendFirst() {
+        Pair<OutgoingMessage, Consumer<Exception>> p = queue.poll();
+        if (p == null) {
+            return;
+        }
+        OutgoingMessage message = p.first;
+        Consumer<Exception> h = p.second;
+        try {
+            // At this point messages are finally ordered and will be written
+            // one by one in a mutually exclusive fashion; thus it's a pretty
+            // convenient place to contextualize them
+            message.contextualize(context);
+            transmitter.send(message, h);
+        } catch (Exception t) {
+            h.accept(t);
+        }
+    }
+
+    @Override
+    public void request(long n) {
+        receiver.request(n);
+    }
+
+    @Override
+    public String getSubprotocol() {
+        return subprotocol;
+    }
+
+    @Override
+    public boolean isClosed() {
+        return closed.get();
+    }
+
+    @Override
+    public void abort() throws IOException {
+        try {
+            channel.close();
+        } finally {
+            closed.set(true);
+            signalClose(CLOSED_ABNORMALLY, "");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return super.toString()
+                + "[" + (closed.get() ? "OPEN" : "CLOSED") + "]: " + uri
+                + (!subprotocol.isEmpty() ? ", subprotocol=" + subprotocol : "");
+    }
+
+    private MessageStreamConsumer messageConsumerOf(Listener listener) {
+        // Synchronization performed here in every method is not for the sake of
+        // ordering invocations to this consumer, after all they are naturally
+        // ordered in the channel. The reason is to avoid an interference with
+        // any unrelated to the channel calls to onOpen, onClose and onError.
+        return new MessageStreamConsumer() {
+
+            @Override
+            public void onText(MessagePart part, CharSequence data) {
+                receiver.acknowledge();
+                synchronized (WebSocketImpl.this.lock) {
+                    try {
+                        listener.onText(WebSocketImpl.this, data, part);
+                    } catch (Exception e) {
+                        signalError(e);
+                    }
+                }
+            }
+
+            @Override
+            public void onBinary(MessagePart part, ByteBuffer data) {
+                receiver.acknowledge();
+                synchronized (WebSocketImpl.this.lock) {
+                    try {
+                        listener.onBinary(WebSocketImpl.this, data.slice(), part);
+                    } catch (Exception e) {
+                        signalError(e);
+                    }
+                }
+            }
+
+            @Override
+            public void onPing(ByteBuffer data) {
+                receiver.acknowledge();
+                // Let's make a full copy of this tiny data. What we want here
+                // is to rule out a possibility the shared data we send might be
+                // corrupted the by processing in the listener.
+                ByteBuffer slice = data.slice();
+                ByteBuffer copy = ByteBuffer.allocate(data.remaining())
+                        .put(data)
+                        .flip();
+                // Non-exclusive send;
+                CompletableFuture<WebSocket> pongSent = enqueue(new Pong(copy));
+                pongSent.whenComplete(
+                        (r, error) -> {
+                            if (error != null) {
+                                WebSocketImpl.this.signalError(error);
+                            }
+                        }
+                );
+                synchronized (WebSocketImpl.this.lock) {
+                    try {
+                        listener.onPing(WebSocketImpl.this, slice);
+                    } catch (Exception e) {
+                        signalError(e);
+                    }
+                }
+            }
+
+            @Override
+            public void onPong(ByteBuffer data) {
+                receiver.acknowledge();
+                synchronized (WebSocketImpl.this.lock) {
+                    try {
+                        listener.onPong(WebSocketImpl.this, data.slice());
+                    } catch (Exception e) {
+                        signalError(e);
+                    }
+                }
+            }
+
+            @Override
+            public void onClose(int statusCode, CharSequence reason) {
+                receiver.acknowledge();
+                processClose(statusCode, reason.toString());
+            }
+
+            @Override
+            public void onError(Exception error) {
+                // An signalError doesn't necessarily mean we must signalClose
+                // the WebSocket. However, if it's something the WebSocket
+                // Specification recognizes as a reason for "Failing the
+                // WebSocket Connection", then we must do so, but BEFORE
+                // notifying the Listener.
+                if (!(error instanceof FailWebSocketException)) {
+                    signalError(error);
+                } else {
+                    Exception ex = (Exception) new ProtocolException().initCause(error);
+                    int code = ((FailWebSocketException) error).getStatusCode();
+                    enqueueClose(new Close(code, ""))
+                            .whenComplete((r, e) -> {
+                                ex.addSuppressed(e);
+                                try {
+                                    channel.close();
+                                } catch (IOException e1) {
+                                    ex.addSuppressed(e1);
+                                } finally {
+                                    closed.set(true);
+                                }
+                                signalError(ex);
+                            });
+                }
+            }
+
+            @Override
+            public void onComplete() {
+                processClose(CLOSED_ABNORMALLY, "");
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketRequest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.incubator.http.internal.websocket;
+
+/*
+ * https://tools.ietf.org/html/rfc6455#section-4.1
+ */
+public interface WebSocketRequest {
+
+    /*
+     * If set to `true` and a proxy is used, instructs the implementation that
+     * a TCP tunnel must be opened.
+     */
+    void isWebSocket(boolean flag);
+
+    /*
+     * Needed for setting "Connection" and "Upgrade" headers as required by the
+     * WebSocket specification.
+     */
+    void setSystemHeader(String name, String value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/package-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * <h2>High level HTTP and WebSocket API</h2>
+ *
+ * This provides a high-level client interfaces to HTTP (versions 1.1 and 2) and
+ * WebSocket. The main types defined are:
+ *
+ * <ul>
+ *    <li>{@link jdk.incubator.http.HttpClient}</li>
+ *    <li>{@link jdk.incubator.http.HttpRequest}</li>
+ *    <li>{@link jdk.incubator.http.HttpResponse}</li>
+ *    <li>{@link jdk.incubator.http.WebSocket}</li>
+ * </ul>
+ *
+ * <p> The API functions asynchronously (using {@link java.util.concurrent.CompletableFuture})
+ * and work is done on the threads supplied by the client's {@link java.util.concurrent.Executor}
+ * where practical.
+ *
+ * <p> {@code HttpClient} also provides a simple synchronous mode, where all
+ * work may be done on the calling thread.
+ *
+ * <p> {@code CompletableFuture}s returned by this API will throw {@link java.lang.UnsupportedOperationException}
+ * for their {@link java.util.concurrent.CompletableFuture#obtrudeValue(Object) obtrudeValue}
+ * and {@link java.util.concurrent.CompletableFuture#obtrudeException(Throwable) obtrudeException}
+ * methods. Invoking the {@link java.util.concurrent.CompletableFuture#cancel cancel}
+ * method on a {@code CompletableFuture} returned by this API will not interrupt
+ * the underlying operation, but may be useful to complete, exceptionally,
+ * dependent stages that have not already completed.
+ *
+ * <p> Unless otherwise stated, {@code null} parameter values will cause methods
+ * of all classes in this package to throw {@code NullPointerException}.
+ *
+ * @since 9
+ */
+package jdk.incubator.http;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * Defines the high-level HTTP and WebSocket API.
+ */
+module jdk.incubator.httpclient {
+    requires java.base;
+    exports jdk.incubator.http;
+}
+
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java	Tue Dec 13 02:04:23 2016 +0100
@@ -40,8 +40,9 @@
         {"6SPACE", "      "},
         {"COMMA", ", "},
 
-        {"provName.not.a.provider", "{0}\u306F\u30D7\u30ED\u30D0\u30A4\u30C0\u3067\u306F\u3042\u308A\u307E\u305B\u3093"},
-        {"signerClass.is.not.a.signing.mechanism", "{0}\u306F\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u3067\u306F\u3042\u308A\u307E\u305B\u3093"},
+        {"provclass.not.a.provider", "%s\u306F\u30D7\u30ED\u30D0\u30A4\u30C0\u3067\u306F\u3042\u308A\u307E\u305B\u3093"},
+        {"provider.name.not.found", "\u30D7\u30ED\u30D0\u30A4\u30C0\u540D\"%s\"\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
+        {"provider.class.not.found", "\u30D7\u30ED\u30D0\u30A4\u30C0\"%s\"\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
         {"jarsigner.error.", "jarsigner\u30A8\u30E9\u30FC: "},
         {"Illegal.option.", "\u4E0D\u6B63\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: "},
         {"This.option.is.deprecated", "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u63A8\u5968\u3067\u3059: "},
@@ -103,10 +104,14 @@
                 "[-protected]                \u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u306F\u4FDD\u8B77\u3055\u308C\u305F\u8A8D\u8A3C\u30D1\u30B9\u304C\u3042\u308B"},
         {".providerName.name.provider.name",
                 "[-providerName <name>]      \u30D7\u30ED\u30D0\u30A4\u30C0\u540D"},
-        {".providerClass.class.name.of.cryptographic.service.provider.s",
-                "[-providerClass <class>     \u6697\u53F7\u5316\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u306E\u540D\u524D"},
-        {".providerArg.arg.master.class.file.and.constructor.argument",
-                "  [-providerArg <arg>]] ... \u30DE\u30B9\u30BF\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3068\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u306E\u5F15\u6570"},
+        {".add.provider.option",
+                "[-addprovider <name>        \u540D\u524D\u3067\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u3092\u8FFD\u52A0\u3059\u308B(SunPKCS11\u306A\u3069)"},
+        {".providerArg.option.1",
+                "  [-providerArg <arg>]] ... -addprovider\u306E\u5F15\u6570\u3092\u69CB\u6210\u3059\u308B"},
+        {".providerClass.option",
+                "[-providerClass <class>     \u5B8C\u5168\u4FEE\u98FE\u30AF\u30E9\u30B9\u540D\u3067\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u3092\u8FFD\u52A0\u3059\u308B"},
+        {".providerArg.option.2",
+                "  [-providerArg <arg>]] ... -providerClass\u306E\u5F15\u6570\u3092\u69CB\u6210\u3059\u308B"},
         {".strict.treat.warnings.as.errors",
                 "[-strict]                   \u8B66\u544A\u3092\u30A8\u30E9\u30FC\u3068\u3057\u3066\u51E6\u7406"},
         {".conf.url.specify.a.pre.configured.options.file",
@@ -134,13 +139,30 @@
                 "  X =\u6307\u5B9A\u3057\u305F\u5225\u540D\u3067\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093"},
         {"no.manifest.", "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306F\u5B58\u5728\u3057\u307E\u305B\u3093\u3002"},
         {".Signature.related.entries.","(\u7F72\u540D\u95A2\u9023\u30A8\u30F3\u30C8\u30EA)"},
-        {".Unsigned.entries.", "(\u672A\u7F72\u540D\u306E\u30A8\u30F3\u30C8\u30EA)"},
-        {"jar.is.unsigned.signatures.missing.or.not.parsable.",
-                "jar\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002(\u7F72\u540D\u304C\u898B\u3064\u304B\u3089\u306A\u3044\u304B\u3001\u69CB\u6587\u89E3\u6790\u3067\u304D\u307E\u305B\u3093)"},
+        {".Unsigned.entries.", "(\u7F72\u540D\u306A\u3057\u306E\u30A8\u30F3\u30C8\u30EA)"},
+        {"jar.is.unsigned",
+                "jar\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
+        {"jar.treated.unsigned",
+                "\u8B66\u544A: \u7F72\u540D\u304C\u69CB\u6587\u89E3\u6790\u3067\u304D\u306A\u3044\u304B\u691C\u8A3C\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u3053\u306Ejar\u306F\u7F72\u540D\u306A\u3057\u3068\u3057\u3066\u6271\u308F\u308C\u307E\u3059\u3002\u8A73\u7D30\u306F\u3001\u30C7\u30D0\u30C3\u30B0\u3092\u6709\u52B9\u306B\u3057\u3066(-J-Djava.security.debug=jar) jarsigner\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
+        {"jar.treated.unsigned.see.weak",
+                "\u3053\u306Ejar\u306F\u3001\u73FE\u5728\u7121\u52B9\u306B\u306A\u3063\u3066\u3044\u308B\u5F31\u3044\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u3067\u7F72\u540D\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\u7F72\u540D\u306A\u3057\u3068\u3057\u3066\u6271\u308F\u308C\u307E\u3059\u3002\n\n\u8A73\u7D30\u306F\u3001-verbose\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066jarsigner\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
+        {"jar.treated.unsigned.see.weak.verbose",
+                "\u8B66\u544A: \u3053\u306Ejar\u306F\u3001\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u306B\u3088\u3063\u3066\u73FE\u5728\u7121\u52B9\u306B\u306A\u3063\u3066\u3044\u308B\u5F31\u3044\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u3067\u7F72\u540D\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\u7F72\u540D\u306A\u3057\u3068\u3057\u3066\u6271\u308F\u308C\u307E\u3059:"},
         {"jar.signed.", "jar\u306F\u7F72\u540D\u3055\u308C\u307E\u3057\u305F\u3002"},
         {"jar.signed.with.signer.errors.", "jar\u306F\u7F72\u540D\u3055\u308C\u307E\u3057\u305F - \u7F72\u540D\u8005\u30A8\u30E9\u30FC\u304C\u3042\u308A\u307E\u3059\u3002"},
         {"jar.verified.", "jar\u304C\u691C\u8A3C\u3055\u308C\u307E\u3057\u305F\u3002"},
         {"jar.verified.with.signer.errors.", "jar\u306F\u691C\u8A3C\u3055\u308C\u307E\u3057\u305F - \u7F72\u540D\u8005\u30A8\u30E9\u30FC\u304C\u3042\u308A\u307E\u3059\u3002"},
+
+        {"history.with.ts", "- \u7F72\u540D\u8005: \"%1$s\"\n    \u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0: %2$s\n    \u7F72\u540D\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0: %3$s\u3001%4$s\n  \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u4ED8\u52A0\u8005: \"%6$s\" \u65E5\u6642: %5$tc\n    \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u306E\u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0: %7$s\n    \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u306E\u7F72\u540D\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0: %8$s\u3001%9$s"},
+        {"history.without.ts", "- \u7F72\u540D\u8005: \"%1$s\"\n    \u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0: %2$s\n    \u7F72\u540D\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0: %3$s\u3001%4$s"},
+        {"history.unparsable", "- \u7F72\u540D\u95A2\u9023\u30D5\u30A1\u30A4\u30EB%s\u3092\u89E3\u6790\u3067\u304D\u307E\u305B\u3093"},
+        {"history.nosf", "- \u7F72\u540D\u95A2\u9023\u30D5\u30A1\u30A4\u30EBMETA-INF/%s.SF\u304C\u3042\u308A\u307E\u305B\u3093"},
+        {"history.nobk", "- \u7F72\u540D\u95A2\u9023\u30D5\u30A1\u30A4\u30EBMETA-INF/%s.SF\u306E\u30D6\u30ED\u30C3\u30AF\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093"},
+
+        {"with.weak", "%s (\u5F31)"},
+        {"key.bit", "%d\u30D3\u30C3\u30C8\u9375"},
+        {"key.bit.weak", "%d\u30D3\u30C3\u30C8\u9375(\u5F31)"},
+
         {"jarsigner.", "jarsigner: "},
         {"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
                 "\u7F72\u540D\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u306B\u4F7F\u7528\u3067\u304D\u308B\u6587\u5B57\u306F\u3001A-Z\u30010-9\u3001_\u3001- \u306E\u307F\u3067\u3059\u3002"},
@@ -198,7 +220,7 @@
         {"Warning.", "\u8B66\u544A: "},
         {"Error.", "\u30A8\u30E9\u30FC: "},
         {"This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked.",
-                "\u3053\u306Ejar\u306B\u306F\u3001\u6574\u5408\u6027\u30C1\u30A7\u30C3\u30AF\u3092\u3057\u3066\u3044\u306A\u3044\u672A\u7F72\u540D\u306E\u30A8\u30F3\u30C8\u30EA\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002 "},
+                "\u3053\u306Ejar\u306B\u306F\u3001\u6574\u5408\u6027\u30C1\u30A7\u30C3\u30AF\u3092\u3057\u3066\u3044\u306A\u3044\u7F72\u540D\u306A\u3057\u306E\u30A8\u30F3\u30C8\u30EA\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002 "},
         {"This.jar.contains.entries.whose.signer.certificate.has.expired.",
                 "\u3053\u306Ejar\u306B\u306F\u3001\u7F72\u540D\u8005\u306E\u8A3C\u660E\u66F8\u304C\u671F\u9650\u5207\u308C\u306E\u30A8\u30F3\u30C8\u30EA\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002 "},
         {"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months.",
@@ -237,6 +259,8 @@
                 "\u7F72\u540D\u8005\u306E\u8A3C\u660E\u66F8\u306F\u81EA\u5DF1\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u3059\u3002"},
         {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
                 "%1$s\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0(%2$s\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u6307\u5B9A)\u306F\u3001\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30EA\u30B9\u30AF\u3068\u307F\u306A\u3055\u308C\u307E\u3059\u3002"},
+        {"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
+                "%s\u7F72\u540D\u9375\u306B\u306F\u3001\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30FB\u30EA\u30B9\u30AF\u3068\u307F\u306A\u3055\u308C\u308B%d\u306E\u9375\u30B5\u30A4\u30BA\u304C\u3042\u308A\u307E\u3059\u3002"},
         {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1",
                  "\u3053\u306Ejar\u306B\u306F\u3001\u8A3C\u660E\u66F8\u30C1\u30A7\u30FC\u30F3\u304C\u307E\u3060\u691C\u8A3C\u3055\u308C\u3066\u3044\u306A\u3044\u30A8\u30F3\u30C8\u30EA\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002\u7406\u7531: %s"},
         {"no.timestamp.signing",
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java	Tue Dec 13 02:04:23 2016 +0100
@@ -40,8 +40,9 @@
         {"6SPACE", "      "},
         {"COMMA", ", "},
 
-        {"provName.not.a.provider", "{0}\u4E0D\u662F\u63D0\u4F9B\u65B9"},
-        {"signerClass.is.not.a.signing.mechanism", "{0}\u4E0D\u662F\u7B7E\u540D\u673A\u5236"},
+        {"provclass.not.a.provider", "%s\u4E0D\u662F\u63D0\u4F9B\u65B9"},
+        {"provider.name.not.found", "\u672A\u627E\u5230\u540D\u4E3A \"%s\" \u7684\u63D0\u4F9B\u65B9"},
+        {"provider.class.not.found", "\u672A\u627E\u5230\u63D0\u4F9B\u65B9 \"%s\""},
         {"jarsigner.error.", "jarsigner \u9519\u8BEF: "},
         {"Illegal.option.", "\u975E\u6CD5\u9009\u9879: "},
         {"This.option.is.deprecated", "\u6B64\u9009\u9879\u5DF2\u8FC7\u65F6: "},
@@ -103,10 +104,14 @@
                 "[-protected]                \u5BC6\u94A5\u5E93\u5177\u6709\u53D7\u4FDD\u62A4\u9A8C\u8BC1\u8DEF\u5F84"},
         {".providerName.name.provider.name",
                 "[-providerName <\u540D\u79F0>]      \u63D0\u4F9B\u65B9\u540D\u79F0"},
-        {".providerClass.class.name.of.cryptographic.service.provider.s",
-                "[-providerClass <\u7C7B>        \u52A0\u5BC6\u670D\u52A1\u63D0\u4F9B\u65B9\u7684\u540D\u79F0"},
-        {".providerArg.arg.master.class.file.and.constructor.argument",
-                "  [-providerArg <\u53C2\u6570>]]... \u4E3B\u7C7B\u6587\u4EF6\u548C\u6784\u9020\u5668\u53C2\u6570"},
+        {".add.provider.option",
+                "[-addprovider <\u540D\u79F0>        \u6309\u540D\u79F0 (\u4F8B\u5982 SunPKCS11) \u6DFB\u52A0\u5B89\u5168\u63D0\u4F9B\u65B9"},
+        {".providerArg.option.1",
+                "  [-providerArg <\u53C2\u6570>]] ... \u914D\u7F6E -addprovider \u7684\u53C2\u6570"},
+        {".providerClass.option",
+                "[-providerClass <\u7C7B>     \u6309\u5168\u9650\u5B9A\u7C7B\u540D\u6DFB\u52A0\u5B89\u5168\u63D0\u4F9B\u65B9"},
+        {".providerArg.option.2",
+                "  [-providerArg <\u53C2\u6570>]] ... \u914D\u7F6E -providerClass \u7684\u53C2\u6570"},
         {".strict.treat.warnings.as.errors",
                 "[-strict]                   \u5C06\u8B66\u544A\u89C6\u4E3A\u9519\u8BEF"},
         {".conf.url.specify.a.pre.configured.options.file",
@@ -135,12 +140,29 @@
         {"no.manifest.", "\u6CA1\u6709\u6E05\u5355\u3002"},
         {".Signature.related.entries.","(\u4E0E\u7B7E\u540D\u76F8\u5173\u7684\u6761\u76EE)"},
         {".Unsigned.entries.", "(\u672A\u7B7E\u540D\u6761\u76EE)"},
-        {"jar.is.unsigned.signatures.missing.or.not.parsable.",
-                "jar \u672A\u7B7E\u540D\u3002(\u7F3A\u5C11\u7B7E\u540D\u6216\u65E0\u6CD5\u5BF9\u7B7E\u540D\u8FDB\u884C\u89E3\u6790)"},
+        {"jar.is.unsigned",
+                "jar \u672A\u7B7E\u540D\u3002"},
+        {"jar.treated.unsigned",
+                "\u8B66\u544A: \u7B7E\u540D\u65E0\u6CD5\u89E3\u6790\u6216\u9A8C\u8BC1, \u8BE5 jar \u5C06\u88AB\u89C6\u4E3A\u672A\u7B7E\u540D\u3002\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u5728\u542F\u7528\u8C03\u8BD5\u7684\u60C5\u51B5\u4E0B\u91CD\u65B0\u8FD0\u884C jarsigner (-J-Djava.security.debug=jar)\u3002"},
+        {"jar.treated.unsigned.see.weak",
+                "\u7531\u4E8E\u8BE5 jar \u662F\u4F7F\u7528\u76EE\u524D\u5DF2\u7981\u7528\u7684\u5F31\u7B97\u6CD5\u7B7E\u540D\u7684, \u56E0\u6B64\u8BE5 jar \u5C06\u88AB\u89C6\u4E3A\u672A\u7B7E\u540D\u3002\n\n\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u4F7F\u7528 -verbose \u9009\u9879\u91CD\u65B0\u8FD0\u884C jarsigner\u3002"},
+        {"jar.treated.unsigned.see.weak.verbose",
+                "\u8B66\u544A: \u8BE5 jar \u5C06\u88AB\u89C6\u4E3A\u672A\u7B7E\u540D, \u56E0\u4E3A\u5B83\u662F\u7531\u76EE\u524D\u5B89\u5168\u5C5E\u6027\u7981\u7528\u7684\u5F31\u7B97\u6CD5\u7B7E\u540D\u7684:"},
         {"jar.signed.", "jar \u5DF2\u7B7E\u540D\u3002"},
         {"jar.signed.with.signer.errors.", "jar \u5DF2\u7B7E\u540D, \u4F46\u51FA\u73B0\u7B7E\u540D\u8005\u9519\u8BEF\u3002"},
         {"jar.verified.", "jar \u5DF2\u9A8C\u8BC1\u3002"},
         {"jar.verified.with.signer.errors.", "jar \u5DF2\u9A8C\u8BC1, \u4F46\u51FA\u73B0\u7B7E\u540D\u8005\u9519\u8BEF\u3002"},
+
+        {"history.with.ts", "- \u7531 \"%1$s\" \u7B7E\u540D\n    \u6458\u8981\u7B97\u6CD5: %2$s\n    \u7B7E\u540D\u7B97\u6CD5: %3$s, %4$s\n  \u7531 \"%6$s\" \u4E8E %5$tc \u52A0\u65F6\u95F4\u6233\n    \u65F6\u95F4\u6233\u6458\u8981\u7B97\u6CD5: %7$s\n    \u65F6\u95F4\u6233\u7B7E\u540D\u7B97\u6CD5: %8$s, %9$s"},
+        {"history.without.ts", "- \u7531 \"%1$s\" \u7B7E\u540D\n    \u6458\u8981\u7B97\u6CD5: %2$s\n    \u7B7E\u540D\u7B97\u6CD5: %3$s, %4$s"},
+        {"history.unparsable", "- \u65E0\u6CD5\u89E3\u6790\u7684\u4E0E\u7B7E\u540D\u76F8\u5173\u7684\u6587\u4EF6 %s"},
+        {"history.nosf", "- \u7F3A\u5C11\u4E0E\u7B7E\u540D\u76F8\u5173\u7684\u6587\u4EF6 META-INF/%s.SF"},
+        {"history.nobk", "- \u4E0E\u7B7E\u540D\u76F8\u5173\u7684\u6587\u4EF6 META-INF/%s.SF \u7F3A\u5C11\u5757\u6587\u4EF6"},
+
+        {"with.weak", "%s (\u5F31)"},
+        {"key.bit", "%d \u4F4D\u5BC6\u94A5"},
+        {"key.bit.weak", "%d \u4F4D\u5BC6\u94A5 (\u5F31)"},
+
         {"jarsigner.", "jarsigner: "},
         {"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
                 "\u7B7E\u540D\u6587\u4EF6\u540D\u5FC5\u987B\u5305\u542B\u4EE5\u4E0B\u5B57\u7B26: A-Z, 0-9, _ \u6216 -"},
@@ -237,6 +259,8 @@
                 "\u7B7E\u540D\u8005\u8BC1\u4E66\u4E3A\u81EA\u7B7E\u540D\u8BC1\u4E66\u3002"},
         {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
                 "\u4E3A %2$s \u9009\u9879\u6307\u5B9A\u7684 %1$s \u7B97\u6CD5\u88AB\u89C6\u4E3A\u5B58\u5728\u5B89\u5168\u98CE\u9669\u3002"},
+        {"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
+                "%s \u7B7E\u540D\u5BC6\u94A5\u7684\u5BC6\u94A5\u5927\u5C0F\u4E3A %d, \u8FD9\u88AB\u89C6\u4E3A\u5B58\u5728\u5B89\u5168\u98CE\u9669\u3002"},
         {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1",
                  "\u6B64 jar \u5305\u542B\u5176\u8BC1\u4E66\u94FE\u672A\u7ECF\u8FC7\u9A8C\u8BC1\u7684\u6761\u76EE\u3002\u539F\u56E0: %s"},
         {"no.timestamp.signing",
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java	Tue Dec 13 02:04:23 2016 +0100
@@ -58,14 +58,14 @@
             // Main operations
             new Option(false, OptionType.MAIN_OPERATION, "--create", "-c") {
                 void process(Main tool, String opt, String arg) throws BadArgs {
-                    if (tool.iflag || tool.tflag || tool.uflag || tool.xflag || tool.printModuleDescriptor)
+                    if (tool.iflag || tool.tflag || tool.uflag || tool.xflag || tool.dflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
                     tool.cflag = true;
                 }
             },
             new Option(true, OptionType.MAIN_OPERATION, "--generate-index", "-i") {
                 void process(Main tool, String opt, String arg) throws BadArgs {
-                    if (tool.cflag || tool.tflag || tool.uflag || tool.xflag || tool.printModuleDescriptor)
+                    if (tool.cflag || tool.tflag || tool.uflag || tool.xflag || tool.dflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
                     tool.iflag = true;
                     tool.rootjar = arg;
@@ -73,21 +73,21 @@
             },
             new Option(false, OptionType.MAIN_OPERATION, "--list", "-t") {
                 void process(Main tool, String opt, String arg) throws BadArgs {
-                    if (tool.cflag || tool.iflag || tool.uflag || tool.xflag || tool.printModuleDescriptor)
+                    if (tool.cflag || tool.iflag || tool.uflag || tool.xflag || tool.dflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
                     tool.tflag = true;
                 }
             },
             new Option(false, OptionType.MAIN_OPERATION, "--update", "-u") {
                 void process(Main tool, String opt, String arg) throws BadArgs {
-                    if (tool.cflag || tool.iflag || tool.tflag || tool.xflag || tool.printModuleDescriptor)
+                    if (tool.cflag || tool.iflag || tool.tflag || tool.xflag || tool.dflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
                     tool.uflag = true;
                 }
             },
             new Option(false, OptionType.MAIN_OPERATION, "--extract", "-x") {
                 void process(Main tool, String opt, String arg) throws BadArgs {
-                    if (tool.cflag || tool.iflag  || tool.tflag || tool.uflag || tool.printModuleDescriptor)
+                    if (tool.cflag || tool.iflag  || tool.tflag || tool.uflag || tool.dflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
                     tool.xflag = true;
                 }
@@ -96,7 +96,7 @@
                 void process(Main tool, String opt, String arg) throws BadArgs {
                     if (tool.cflag || tool.iflag  || tool.tflag || tool.uflag || tool.xflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
-                    tool.printModuleDescriptor = true;
+                    tool.dflag = true;
                 }
             },
 
@@ -248,7 +248,7 @@
     static int parseOptions(Main jartool, String[] args) throws BadArgs {
         int count = 0;
         if (args.length == 0) {
-            jartool.info = Main.Info.USAGE_SUMMARY;
+            jartool.info = Main.Info.USAGE_TRYHELP;
             return 0;
         }
 
@@ -318,8 +318,7 @@
         out.format("%s%n", Main.getMsg("usage.compat"));
     }
 
-    static void printUsageSummary(PrintWriter out) {
-        out.format("%s%n", Main.getMsg("main.usage.summary"));
+    static void printUsageTryHelp(PrintWriter out) {
         out.format("%s%n", Main.getMsg("main.usage.summary.try"));
     }
 
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Tue Dec 13 02:04:23 2016 +0100
@@ -204,14 +204,15 @@
      * iflag: generate jar index
      * nflag: Perform jar normalization at the end
      * pflag: preserve/don't strip leading slash and .. component from file name
+     * dflag: print module descriptor
      */
-    boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag;
+    boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, dflag;
 
     /* To support additional GNU Style informational options */
     enum Info {
         HELP(GNUStyleOptions::printHelp),
         COMPAT_HELP(GNUStyleOptions::printCompatHelp),
-        USAGE_SUMMARY(GNUStyleOptions::printUsageSummary),
+        USAGE_TRYHELP(GNUStyleOptions::printUsageTryHelp),
         VERSION(GNUStyleOptions::printVersion);
 
         private Consumer<PrintWriter> printFunction;
@@ -220,8 +221,8 @@
     };
     Info info;
 
+
     /* Modular jar related options */
-    boolean printModuleDescriptor;
     Version moduleVersion;
     Pattern modulesToHash;
     ModuleFinder moduleFinder = ModuleFinder.of();
@@ -509,7 +510,7 @@
             } else if (iflag) {
                 String[] files = filesMap.get(BASE_VERSION);  // base entries only, can be null
                 genIndex(rootjar, files);
-            } else if (printModuleDescriptor) {
+            } else if (dflag) {
                 boolean found;
                 if (fname != null) {
                     try (ZipFile zf = new ZipFile(fname)) {
@@ -671,14 +672,16 @@
                 try {
                     count = GNUStyleOptions.parseOptions(this, args);
                 } catch (GNUStyleOptions.BadArgs x) {
-                    if (info != null) {
-                        info.print(out);
-                        return true;
+                    if (info == null) {
+                        error(x.getMessage());
+                        if (x.showUsage)
+                            Info.USAGE_TRYHELP.print(err);
+                        return false;
                     }
-                    error(x.getMessage());
-                    if (x.showUsage)
-                        Info.USAGE_SUMMARY.print(err);
-                    return false;
+                }
+                if (info != null) {
+                    info.print(out);
+                    return true;
                 }
             } else {
                 // Legacy/compatibility options
@@ -689,28 +692,28 @@
                     switch (flags.charAt(i)) {
                         case 'c':
                             if (xflag || tflag || uflag || iflag) {
-                                usageError();
+                                usageError(getMsg("error.multiple.main.operations"));
                                 return false;
                             }
                             cflag = true;
                             break;
                         case 'u':
                             if (cflag || xflag || tflag || iflag) {
-                                usageError();
+                                usageError(getMsg("error.multiple.main.operations"));
                                 return false;
                             }
                             uflag = true;
                             break;
                         case 'x':
                             if (cflag || uflag || tflag || iflag) {
-                                usageError();
+                                usageError(getMsg("error.multiple.main.operations"));
                                 return false;
                             }
                             xflag = true;
                             break;
                         case 't':
                             if (cflag || uflag || xflag || iflag) {
-                                usageError();
+                                usageError(getMsg("error.multiple.main.operations"));
                                 return false;
                             }
                             tflag = true;
@@ -732,7 +735,7 @@
                             break;
                         case 'i':
                             if (cflag || uflag || xflag || tflag) {
-                                usageError();
+                                usageError(getMsg("error.multiple.main.operations"));
                                 return false;
                             }
                             // do not increase the counter, files will contain rootjar
@@ -749,35 +752,27 @@
                             pflag = true;
                             break;
                         default:
-                            error(formatMsg("error.illegal.option",
-                                    String.valueOf(flags.charAt(i))));
-                            usageError();
+                            usageError(formatMsg("error.illegal.option",
+                                       String.valueOf(flags.charAt(i))));
                             return false;
                     }
                 }
             }
         } catch (ArrayIndexOutOfBoundsException e) {
-            usageError();
+            usageError(getMsg("main.usage.summary"));
+            return false;
+        }
+        if (!cflag && !tflag && !xflag && !uflag && !iflag && !dflag) {
+            usageError(getMsg("error.bad.option"));
             return false;
         }
 
-        if (info != null) {
-            info.print(out);
-            return true;
-        }
-
-        if (!cflag && !tflag && !xflag && !uflag && !iflag && !printModuleDescriptor) {
-            error(getMsg("error.bad.option"));
-            usageError();
-            return false;
-        }
         /* parse file arguments */
         int n = args.length - count;
         if (n > 0) {
-            if (printModuleDescriptor) {
+            if (dflag) {
                 // "--print-module-descriptor/-d" does not require file argument(s)
-                error(formatMsg("error.bad.dflag", args[count]));
-                usageError();
+                usageError(formatMsg("error.bad.dflag", args[count]));
                 return false;
             }
             int version = BASE_VERSION;
@@ -806,8 +801,7 @@
                             // this will fall into the next error, thus returning false
                         }
                         if (v < 9) {
-                            error(formatMsg("error.release.value.toosmall", String.valueOf(v)));
-                            usageError();
+                            usageError(formatMsg("error.release.value.toosmall", String.valueOf(v)));
                             return false;
                         }
                         // associate the files, if any, with the previous version number
@@ -827,7 +821,7 @@
                     }
                 }
             } catch (ArrayIndexOutOfBoundsException e) {
-                usageError();
+                usageError(getMsg("error.bad.file.arg"));
                 return false;
             }
             // associate remaining files, if any, with a version
@@ -838,16 +832,14 @@
                 isMultiRelease = version > BASE_VERSION;
             }
         } else if (cflag && (mname == null)) {
-            error(getMsg("error.bad.cflag"));
-            usageError();
+            usageError(getMsg("error.bad.cflag"));
             return false;
         } else if (uflag) {
             if ((mname != null) || (ename != null)) {
                 /* just want to update the manifest */
                 return true;
             } else {
-                error(getMsg("error.bad.uflag"));
-                usageError();
+                usageError(getMsg("error.bad.uflag"));
                 return false;
             }
         }
@@ -1354,8 +1346,7 @@
         if (ename != null) {
             Attributes global = m.getMainAttributes();
             if ((global.get(Attributes.Name.MAIN_CLASS) != null)) {
-                error(getMsg("error.bad.eflag"));
-                usageError();
+                usageError(getMsg("error.bad.eflag"));
                 return true;
             }
         }
@@ -1831,8 +1822,9 @@
     /**
      * Prints usage message.
      */
-    void usageError() {
-        Info.USAGE_SUMMARY.print(err);
+    void usageError(String s) {
+        err.println(s);
+        Info.USAGE_TRYHELP.print(err);
     }
 
     /**
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,7 +24,7 @@
 #
 
 error.multiple.main.operations=\
-     You may not specify more than one '-cuxti' options
+     You may not specify more than one '-cuxtid' options
 error.cant.open=\
      can''t open: {0}
 error.illegal.option=\
@@ -175,7 +175,7 @@
 \ \      jar cvfm classes.jar mymanifest -C foo/ .\n
 
 main.usage.summary=\
-jar: You must specify one of -ctxui options.
+Usage: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=\
 Try `jar --help' for more information.
 
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=Sie k\u00F6nnen nicht mehrere "-cuxti"-Optionen angeben
+error.multiple.main.operations=Sie k\u00F6nnen nicht mehrere "-cuxtid"-Optionen angeben
 error.cant.open=\u00D6ffnen nicht m\u00F6glich: {0}
 error.illegal.option=Ung\u00FCltige Option: {0}
 error.unrecognized.option=Unbekannte Option: {0}
@@ -53,6 +53,19 @@
 error.missing.provider=Serviceprovider nicht gefunden: {0}
 error.release.value.notnumber=Release {0} nicht g\u00FCltig
 error.release.value.toosmall=Release {0} nicht g\u00FCltig, muss >= 9 sein
+error.validator.jarfile.exception={0} kann nicht validiert werden: {1}
+error.validator.jarfile.invalid=ung\u00FCltige Multi-Release-JAR-Datei {0} gel\u00F6scht
+error.validator.bad.entry.name=Eintragsname hat das falsche Format, {0}
+error.validator.version.notnumber=Eintragsname {0} hat keine Versionsnummer
+error.validator.entryname.tooshort=Eintragsname {0} zu kurz, kein Verzeichnis
+error.validator.isolated.nested.class=Eintrag {0} ist eine isolierte verschachtelte Klasse
+error.validator.new.public.class=Eintrag {0} enth\u00E4lt eine neue \u00F6ffentliche Klasse, die in Basiseintr\u00E4gen nicht gefunden wird
+error.validator.incompatible.class.version=Eintrag {0} weist eine Klassenversion auf, die mit einer fr\u00FCheren Version inkompatibel ist
+error.validator.different.api=Eintrag {0} enth\u00E4lt eine Klasse mit einer anderen API als in der fr\u00FCheren Version
+error.validator.names.mismatch=Eintrag {0} enth\u00E4lt eine Klasse mit dem internen Namen {1}, Namen stimmen nicht \u00FCberein
+warn.validator.identical.entry=Warnung - Eintrag {0} enth\u00E4lt eine Klasse, die mit einem Eintrag identisch ist, der bereits in der JAR-Datei enthalten ist
+warn.validator.resources.with.same.name=Warnung - Eintrag {0}, mehrere Ressourcen mit demselben Namen
+warn.validator.concealed.public.class=Warnung - Eintrag {0} ist eine \u00F6ffentliche Klasse in einem verdeckten Package, \nwenn diese JAR-Datei in den Classpath gesetzt wird, kommt es zu nicht kompatiblen \u00F6ffentlichen Schnittstellen
 out.added.manifest=Manifest wurde hinzugef\u00FCgt
 out.added.module-info=module-info hinzugef\u00FCgt: {0}
 out.update.manifest=Manifest wurde aktualisiert
@@ -68,7 +81,7 @@
 
 usage.compat=Kompatibilit\u00E4tsschnittstelle:\nVerwendung:  jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien] ...\nOptionen:\n    -c  Neues Archiv erstellen\n    -t  Inhaltsverzeichnis f\u00FCr Archiv anzeigen\n    -x  Benannte (oder alle) Dateien aus Archiv extrahieren\n    -u  Vorhandenes Archiv aktualisieren\n    -v  Ausgabe im Verbose-Modus aus Standardausgabe generieren\n    -f  Dateinamen f\u00FCr Archiv angeben\n    -m  Manifestinformationen aus angegebener Manifestdatei aufnehmen\n    -n  Pack200-Normalisierung nach Erstellung eines neuen Archivs ausf\u00FChren\n    -e  Anwendungseinstiegspunkt f\u00FCr in ausf\u00FChrbare JAR-Datei \n        geb\u00FCndelte Standalone-Anwendung angeben\n    -0  Nur speichern; keine ZIP-Komprimierung verwenden\n    -P  Komponenten mit vorangestelltem "/" (absoluter Pfad) und ".." (\u00FCbergeordnetes Verzeichnis) aus Dateinamen beibehalten\n        -M  Keine Manifestdatei f\u00FCr die Eintr\u00E4ge erstellen\n    -i  Indexinformationen f\u00FCr die angegebenen JAR-Dateien erstellen\n    -C  Zum angegebenen Verzeichnis wechseln und folgende Datei ber\u00FCcksichtigen\nDateien, die Verzeichnisse sind, werden rekursiv verarbeitet.\nDer Name der Manifestdatei, der Name der Archivdatei und der Name des Einstiegspunktes werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Zwei Klassendateien in ein Archiv "classes.jar" archivieren: \n       jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Mit der vorhandenen Manifestdatei "mymanifest" alle\n           Dateien im Verzeichnis foo/ in "classes.jar" archivieren: \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: Sie m\u00FCssen eine -ctxui-Option angeben.
+main.usage.summary=Verwendung: jar [OPTION...] [ [--release VERSION] [-C dir] Dateien] ...
 main.usage.summary.try=Verwenden Sie "jar --help", um weitere Informationen anzuzeigen.
 
 main.help.preopt=Verwendung: jar [OPTION...] [ [--release VERSION] [-C dir] Dateien] ...\njar erstellt ein Archiv f\u00FCr Klassen und Ressourcen und kann individuelle\nKlassen oder Ressourcen aus einem Archiv bearbeiten oder wiederherstellen.\n\n Beispiele:\n # Ein Archiv namens classes.jar mit zwei Klassendateien erstellen:\n jar --create --file classes.jar Foo.class Bar.class\n # Ein Archiv mit einem vorhandenen Manifest mit allen Dateien in foo/ erstellen:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # Ein modulares JAR-Archiv erstellen, dessen Moduldeskriptor sich in\n # classes/module-info.class befindet:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # Ein vorhandenes nicht modulares JAR-Archiv in ein modulares JAR-Archiv aktualisieren:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # Multi-Release-JAR-Datei erstellen, wobei einige Dateien in das Verzeichnis META-INF/versions/9 gespeichert werden:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 Das Inhaltsverzeichnis f\u00FCr das Archiv auflisten
 main.help.opt.main.update=\  -u, --update               Ein vorhandenes JAR-Archiv aktualisieren
 main.help.opt.main.extract=\  -x, --extract              Benannte (oder alle) Dateien aus dem Archiv extrahieren
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  Moduldeskriptor drucken
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  Moduldeskriptor drucken
 main.help.opt.any=\ In jedem Modus g\u00FCltige Vorgangsmodifikatoren:\n\n  -C DIR                     Zum angegebenen Verzeichnis wechseln und die folgende\n                             Datei aufnehmen
 main.help.opt.any.file=-f, --file=FILE            Der Name der Archivdatei\n      --release VERSION      Die folgenden Dateien werden in ein versioniertes Verzeichnis\n                             der JAR-Datei gespeichert (d.h. META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              Verbose-Ausgabe bei Standardausgabe generieren
@@ -88,8 +101,7 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          Keine Manifestdatei f\u00FCr die Eintr\u00E4ge erstellen
 main.help.opt.create.update.module-version=\      --module-version=VERSION    Die Modulversion beim Erstellen eines modularen\n                             JAR-Archivs oder Aktualisieren eines nicht modularen JAR-Archivs
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN Berechnet und zeichnet die Hashes von Modulen auf, \n                             die mit einem bestimmten Muster \u00FCbereinstimmen, und direkt oder\n                             indirekt von einem modularen JAR-Archiv abh\u00E4ngen, das erstellt\n                             wird, oder einem nicht-modularen JAR-Archiv, das aktualisiert wird
-main.help.opt.create.update.modulepath=\      --modulepath           Ort von Modulabh\u00E4ngigkeit zum Generieren
-\                             des Hash
+main.help.opt.create.update.module-path=\  -p, --module-path         Speicherort von Modulabh\u00E4ngigkeit zur Generierung\n                             von Hash
 main.help.opt.create.update.index=\ Vorgangsmodifikatoren, die nur im Erstellungs-, Aktualisierungs- und Indexgenerierungsmodus g\u00FCltig sind:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          Nur speichern, keine ZIP-Komprimierung verwenden
 main.help.opt.other=\ Weitere Optionen:\n
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_es.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_es.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=No se puede especificar m\u00E1s de una opci\u00F3n '-cuxti'
+error.multiple.main.operations=No se puede especificar m\u00E1s de una opci\u00F3n '-cuxtid'
 error.cant.open=no se puede abrir: {0}
 error.illegal.option=Opci\u00F3n no permitida: {0}
 error.unrecognized.option=opci\u00F3n no reconocida: {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=No se ha encontrado el descriptor de m\u00F3dulo
 error.versioned.info.without.root=Se ha encontrado module-info.class en un directorio con versi\u00F3n sin module-info.class en la ra\u00EDz
 error.versioned.info.name.notequal=module-info.class en un directorio con versi\u00F3n contiene un nombre incorrecto
-error.versioned.info.requires.public=module-info.class en un directorio con versi\u00F3n contiene requisitos p\u00FAblicos adicionales
-error.versioned.info.requires.added=module-info.class en un directorio con versi\u00F3n contiene requisitos adicionales
-error.versioned.info.requires.dropped=module-info.class en un directorio con versi\u00F3n contiene requisitos que faltan
-error.versioned.info.exports.notequal=module-info.class en un directorio con versi\u00F3n contiene exportaciones diferentes
-error.versioned.info.provides.notequal=module-info.class en un directorio con versi\u00F3n contiene aportaciones diferentes
+error.versioned.info.requires.public=module-info.class en un directorio con versiones contiene "requires public" adicionales
+error.versioned.info.requires.added=module-info.class en un directorio con versi\u00F3n contiene "requires" adicionales
+error.versioned.info.requires.dropped=module-info.class en un directorio con versiones contiene "requires" que faltan
+error.versioned.info.exports.notequal=module-info.class en un directorio con versiones contiene "exports" diferentes
+error.versioned.info.provides.notequal=module-info.class en un directorio con versiones contiene "provides" diferentes
 error.invalid.versioned.module.attribute=Atributo de descriptor de m\u00F3dulo no v\u00E1lido {0}
 error.missing.provider=No se ha encontrado el proveedor de servicios: {0}
 error.release.value.notnumber=versi\u00F3n {0} no v\u00E1lida
 error.release.value.toosmall=versi\u00F3n {0} no v\u00E1lida, debe ser >= 9
+error.validator.jarfile.exception=no puede validar {0}: {1}
+error.validator.jarfile.invalid=se ha suprimido el archivo jar de varias versiones {0} no v\u00E1lido
+error.validator.bad.entry.name=nombre de entrada con formato incorrecto, {0}
+error.validator.version.notnumber=el nombre de entrada {0} no tiene un n\u00FAmero de versi\u00F3n
+error.validator.entryname.tooshort=el nombre de entrada {0} es demasiado corto, no es un directorio
+error.validator.isolated.nested.class=la entrada {0} es una clase anidada aislada
+error.validator.new.public.class=la entrada {0} contiene una nueva clase p\u00FAblica que no est\u00E1 en las entradas de base
+error.validator.incompatible.class.version=la entrada {0} tiene una versi\u00F3n de clase no compatible con una versi\u00F3n anterior
+error.validator.different.api=la entrada {0} contiene una clase con una api diferente de la versi\u00F3n anterior
+error.validator.names.mismatch=la entrada {0} contiene una clase con un nombre interno {1}, los nombres no coinciden
+warn.validator.identical.entry=advertencia: la entrada {0} contiene una clase id\u00E9ntica a una entrada que ya est\u00E1 en el archivo jar
+warn.validator.resources.with.same.name=advertencia: la entrada {0} tiene varios recursos con el mismo nombre
+warn.validator.concealed.public.class=advertencia: la entrada {0} es una clase p\u00FAblica en un paquete oculto. \ncolocar este jar en la ruta de clase tendr\u00E1 como resultado interfaces p\u00FAblicas no compatibles
 out.added.manifest=manifiesto agregado
 out.added.module-info=module-info agregado: {0}
 out.update.manifest=manifiesto actualizado
@@ -68,7 +81,7 @@
 
 usage.compat=Interfaz de compatibilidad:\nSintaxis: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files] ...Opciones: \n    -c  crear nuevo archivo\n    -t  mostrar la tabla de contenido del archivo\n    -x   extraer el archivo mencionado (o todos) del archivo\n    -u  actualizar archivo existente\n    -v  generar salida detallada de los datos de salida est\u00E1ndar\n    -f  especificar nombre del archivo de almacenamiento\n    -m  incluir informaci\u00F3n de manifiesto del archivo de manifiesto especificado n    -n  realizar la normalizaci\u00F3n Pack200 despu\u00E9s de crear un archivo nuevo\n    -e  especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n        que se incluye dentro de un archivo jar ejecutable\n    -0  solo almacenar; no utilizar compresi\u00F3n ZIP\n    -P  conservar componentes iniciales '/' (ruta absoluta) y ".." (directorio principal) en los nombres de archivo\n    -M  no crear un archivo de manifiesto para las entradas\n    -i  generar informaci\u00F3n de \u00EDndice para los archivos jar especificados\n    -C  cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente. \nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\n especifican en el mismo orden que los indicadores 'm', 'f' y 'e'. \n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n       jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\n           archivos del directorio foo/ en 'classes.jar': \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: Debe especificar una de las opciones -ctxui.
+main.usage.summary=Sintaxis: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=Intente `jar --help' para obtener m\u00E1s informaci\u00F3n.
 
 main.help.preopt=Sintaxis: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar crea un archivo para las clases y recursos y puede manipular o\nrestaurar clases individuales o recursos de un archivo.\n\n Ejemplos:\n # Crear un archivo denominado classes.jar con dos archivos de clase:\n jar --create --file classes.jar Foo.class Bar.class\n # Crear un archivo con un manifiesto existente, con todos los archivos en foo/:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # Crear un archivo jar modular, donde el descriptor de m\u00F3dulo est\u00E1 en\n # classes/module-info.class:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # Actualizar un jar no modular en un jar modular:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # Crear un archivo jar de varias versiones y colocar algunos archivos en el directorio META-INF/versions/9:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 Mostrar la tabla de contenido del archivo
 main.help.opt.main.update=\  -u, --update               Actualizar un archivo jar existente
 main.help.opt.main.extract=\  -x, --extract              Extraer determinados (o todos) los archivos del archivo
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  Imprimir el descriptor de m\u00F3dulo
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  Imprimir el descriptor de m\u00F3dulo
 main.help.opt.any=\ Modificadores de operaci\u00F3n v\u00E1lidos en cualquier modo:\n\n  -C DIR                     Cambiar al directorio especificado e incluir el\n                             siguiente archivo
 main.help.opt.any.file=\  -f, --file=FILE            Nombre del archivo\n      --release VERSION      Se colocan todos los archivos siguientes en un directorio con versi\u00F3n\n                             del archivo jar (es decir, META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              Generar salida verbose en salida est\u00E1ndar
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          No crear ning\u00FAn archivo de manifiesto para las entradas
 main.help.opt.create.update.module-version=\      --module-version=VERSION    Versi\u00F3n del m\u00F3dulo, si se va a crear un archivo jar modular\n                             o actualizar un archivo jar no modular
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN Calcular y registrar los hash de m\u00F3dulos\n                             que coinciden con el patr\u00F3n proporcionado y que dependen\n                             directa o indirectamente de la creaci\u00F3n de un archivo jar modular\n                             o de la actualizaci\u00F3n de un archivo jar no modular
-main.help.opt.create.update.modulepath=\      --modulepath           Ubicaci\u00F3n de la dependencia de m\u00F3dulo para generaci\u00F3n
-\                             hash
+main.help.opt.create.update.module-path=\  -p, --module-path          Ubicaci\u00F3n de la dependencia de m\u00F3dulo para generar\n                             el hash
 main.help.opt.create.update.index=\ Modificadores de operaci\u00F3n v\u00E1lidos solo en el modo de creaci\u00F3n, actualizaci\u00F3n y generaci\u00F3n de \u00EDndice:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          Solo almacenar; no usar compresi\u00F3n ZIP
 main.help.opt.other=\ Otras opciones:\n
 main.help.opt.other.help=\  -?, --help[:compat]        Utilice este valor, u opcionalmente la compatibilidad, ayuda
 main.help.opt.other.version=\      --version              Imprimir versi\u00F3n del programa
-main.help.postopt=\ Un archivo es un jar modular si el descriptor de m\u00F3dulo, 'module-info.class', est\u00E1\n en la ra\u00EDz de los directorios proporcionados o en la ra\u00EDz del archivo jar.\n Las siguientes operaciones solo son v\u00E1lidas si se va a crear un jar modular\n o se va a actualizar un jar existente no modular: '--module-version',\n '--hash-modules' y '--modulepath'.\n\n Los argumentos obligatorios u opcionales en las opciones largas tambi\u00E9n son obligatorios u opcionales\n en cualquiera de las opciones cortas.
+main.help.postopt=\ Un archivo es un jar modular si el descriptor de m\u00F3dulo, 'module-info.class', est\u00E1\n en la ra\u00EDz de los directorios proporcionados o en la ra\u00EDz del archivo jar.\n Las siguientes operaciones solo son v\u00E1lidas si se va a crear un archivo jar modular\n o se va a actualizar un jar existente no modular: '--module-version',\n '--hash-modules' y '--module-path'.\n\n Los argumentos obligatorios u opcionales en las opciones largas tambi\u00E9n son obligatorios u opcionales\n en cualquiera de las opciones cortas.
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_fr.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_fr.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=Vous ne pouvez pas sp\u00E9cifier plus d'une option '-cuxti'
+error.multiple.main.operations=Vous ne pouvez pas sp\u00E9cifier plus d'une option '-cuxtid'
 error.cant.open=impossible d''ouvrir : {0}
 error.illegal.option=Option non admise : {0}
 error.unrecognized.option=option non reconnue : {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=Descripteur de module introuvable
 error.versioned.info.without.root=module-info.class a \u00E9t\u00E9 d\u00E9tect\u00E9 dans un r\u00E9pertoire avec num\u00E9ro de version sans module-info.class dans la racine
 error.versioned.info.name.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient un nom incorrect
-error.versioned.info.requires.public=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des exigences publiques suppl\u00E9mentaires
-error.versioned.info.requires.added=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des exigences suppl\u00E9mentaires
-error.versioned.info.requires.dropped=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des exigences manquantes
-error.versioned.info.exports.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des exports diff\u00E9rents
-error.versioned.info.provides.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des fournitures diff\u00E9rentes
+error.versioned.info.requires.public=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires public" suppl\u00E9mentaires
+error.versioned.info.requires.added=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires" suppl\u00E9mentaires
+error.versioned.info.requires.dropped=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires" manquants
+error.versioned.info.exports.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "exports" diff\u00E9rents
+error.versioned.info.provides.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "provides" diff\u00E9rents
 error.invalid.versioned.module.attribute=Attribut de descripteur de module non valide {0}
 error.missing.provider=Fournisseur de services introuvable : {0}
 error.release.value.notnumber=version {0} non valide
 error.release.value.toosmall=version {0} non valide : elle doit \u00EAtre sup\u00E9rieure ou \u00E9gale \u00E0 9
+error.validator.jarfile.exception=Impossible de valider {0} : {1}
+error.validator.jarfile.invalid=fichier JAR multiversion non valide {0} supprim\u00E9
+error.validator.bad.entry.name=nom d''entr\u00E9e au format incorrect, {0}
+error.validator.version.notnumber=le nom d''entr\u00E9e : {0} n''a pas de num\u00E9ro de version
+error.validator.entryname.tooshort=le nom d''entr\u00E9e : {0} est trop court et n''est pas un r\u00E9pertoire
+error.validator.isolated.nested.class=l''entr\u00E9e : {0} est une classe isol\u00E9e imbriqu\u00E9e
+error.validator.new.public.class=l''entr\u00E9e : {0} contient une nouvelle classe publique introuvable dans les entr\u00E9es de base
+error.validator.incompatible.class.version=l''entr\u00E9e : {0} a une version de classe non compatible avec une version ant\u00E9rieure
+error.validator.different.api=l''entr\u00E9e : {0} contient une classe avec une API diff\u00E9rente de la version ant\u00E9rieure
+error.validator.names.mismatch=l''entr\u00E9e : {0} contient une classe avec le nom interne {1}, les noms ne concordent pas
+warn.validator.identical.entry=avertissement - l''entr\u00E9e : {0} contient une classe identique \u00E0 une entr\u00E9e qui se trouve d\u00E9j\u00E0 dans le fichier JAR
+warn.validator.resources.with.same.name=avertissement - entr\u00E9e : {0}, plusieurs ressources du m\u00EAme nom
+warn.validator.concealed.public.class=avertissement - l''entr\u00E9e {0} est une classe publique dans un package dissimul\u00E9, \nle placement de ce fichier JAR sur le chemin de classe g\u00E9n\u00E9rera des interfaces publiques incompatibles
 out.added.manifest=manifeste ajout\u00E9
 out.added.module-info=module-info ajout\u00E9 : {0}
 out.update.manifest=manifeste mis \u00E0 jour
@@ -68,7 +81,7 @@
 
 usage.compat=Interface de compatibilit\u00E9 :\nSyntaxe : jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOptions :\n    -c  cr\u00E9e une archive\n    -t  affiche la table des mati\u00E8res de l'archive\n    -x  extrait des fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n    -u  met \u00E0 jour l'archive existante\n    -v  g\u00E9n\u00E8re une sortie en mode verbose d'une sortie standard\n    -f  sp\u00E9cifie le nom de fichier d'archive\n    -m  inclut les informations de manifeste \u00E0 partir du fichier manifeste sp\u00E9cifi\u00E9\n    -n  effectue une normalisation Pack200 apr\u00E8s la cr\u00E9ation d'une archive\n    -e  sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n        int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n    -0  stockage uniquement, pas de compression ZIP\n    -P  pr\u00E9serve les signes de d\u00E9but '/' (chemin absolu) et ".." (r\u00E9pertoire parent) dans les noms de fichier\n    -M  ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es\n    -i  g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n    -C  passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifeste, du fichier d'archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n       jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifeste existant 'mymanifest', puis archiver tous les\n           fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar : vous devez sp\u00E9cifier l'une des options -ctxui.
+main.usage.summary=Syntaxe : jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=Pour plus d'informations, essayez 'jar --help'.
 
 main.help.preopt=Syntaxe : jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar cr\u00E9e une archive pour les classes et les ressources, et peut manipuler ou\nrestaurer les classes ou ressources individuelles \u00E0 partir d'une archive.\n\n Exemples :\n # Cr\u00E9ation d'une archive nomm\u00E9e classes.jar compos\u00E9e de deux fichiers de classe :\n jar --create --file classes.jar Foo.class Bar.class\n # Cr\u00E9ation d'une archive \u00E0 l'aide d'un manifeste existant, avec tous les fichiers dans foo/ :\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # Cr\u00E9ation d'une archive JAR modulaire, o\u00F9 le descripteur de module est situ\u00E9 dans\n # classes/module-info.class :\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # Mise \u00E0 jour d'un fichier JAR non modulaire existant vers un fichier JAR modulaire :\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # Cr\u00E9e un fichier JAR multiversion en pla\u00E7ant certains fichiers dans le r\u00E9pertoire META-INF/versions/9 :\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 Affiche la table des mati\u00E8res de l'archive
 main.help.opt.main.update=\  -u, --update               Met \u00E0 jour une archive JAR existante
 main.help.opt.main.extract=\  -x, --extract              Extrait des fichiers nomm\u00E9s (ou tous les fichiers) de l'archive
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  Imprime le descripteur de module
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  Imprime le descripteur de module
 main.help.opt.any=\ Modificateurs d'op\u00E9ration valides pour tous les modes :\n\n  -C DIR                     Passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le\n                             fichier suivant
 main.help.opt.any.file=\  -f, --file=FILE            Nom de fichier d'archive\n      --release VERSION      Place tous les fichiers suivants dans un r\u00E9pertoire avec num\u00E9ro de version\n                             du fichier JAR (par exemple, META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              G\u00E9n\u00E8re une sortie en mode verbose d'une sortie standard
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          Ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es
 main.help.opt.create.update.module-version=\      --module-version=VERSION    Version de module lors de la cr\u00E9ation d'un fichier JAR\n                             modulaire ou de la mise \u00E0 jour d'un fichier JAR non modulaire
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN Calcule et enregistre les hachages des modules \n                             mis en correspondance d'apr\u00E8s le mod\u00E8le donn\u00E9 et d\u00E9pendant\n                             directement ou indirectement d'un fichier JAR modulaire\n                             en cours de cr\u00E9ation ou d'un fichier JAR non modulaire en cours de mise \u00E0 jour
-main.help.opt.create.update.modulepath=\      --modulepath           Emplacement d'une d\u00E9pendance de module pour la g\u00E9n\u00E9ration
-\                             du hachage
+main.help.opt.create.update.module-path=\  -p, --module-path          Emplacement de la d\u00E9pendance de module pour la g\u00E9n\u00E9ration\n                             du hachage
 main.help.opt.create.update.index=\ Modificateurs d'op\u00E9ration valides uniquement en modes create, update et generate-index :\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          Stocke uniquement ; n'utilise pas de compression ZIP
 main.help.opt.other=\ Autres options :\n
 main.help.opt.other.help=\  -?, --help[:compat]        Affiche l'aide ou \u00E9ventuellement la compatibilit\u00E9
 main.help.opt.other.version=\      --version              Imprime la version de programme
-main.help.postopt=\ Une archive est un fichier JAR modulaire si un descripteur de module, 'module-info.class', se\n trouve dans la racine des r\u00E9pertoires donn\u00E9s ou dans la racine de l'archive JAR\n elle-m\u00EAme. Les op\u00E9rations suivantes sont valides uniquement lors de la cr\u00E9ation d'un fichier JAR modulaire\n ou de la mise \u00E0 jour d'un fichier JAR non modulaire existant : '--module-version',\n '--hash-modules' et '--modulepath'.\n\n Les arguments obligatoires ou facultatifs pour les options longues sont \u00E9galement obligatoires ou facultatifs\n pour toute option courte correspondante.
+main.help.postopt=\ Une archive est un fichier JAR modulaire si un descripteur de module, 'module-info.class', se\n trouve dans la racine des r\u00E9pertoires donn\u00E9s ou dans la racine de l'archive JAR\n elle-m\u00EAme. Les op\u00E9rations suivantes sont valides uniquement lors de la cr\u00E9ation d'un fichier JAR modulaire\n ou de la mise \u00E0 jour d'un fichier JAR non modulaire existant : '--module-version',\n '--hash-modules' et '--module-path'.\n\n Les arguments obligatoires ou facultatifs pour les options longues sont \u00E9galement obligatoires ou facultatifs\n pour toute option courte correspondante.
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_it.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_it.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=Impossibile specificare pi\u00F9 di un'opzione '-cuxti'
+error.multiple.main.operations=Impossibile specificare pi\u00F9 di un'opzione '-cuxtid'
 error.cant.open=impossibile aprire: {0}
 error.illegal.option=Opzione non valida: {0}
 error.unrecognized.option=opzione non riconosciuta: {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=Descrittore di modulo non trovato
 error.versioned.info.without.root=module-info.class trovato in una directory con controllo delle versioni senza module-info.class nella radice
 error.versioned.info.name.notequal=module-info.class in una directory con controllo delle versioni contiene un nome errato
-error.versioned.info.requires.public=module-info.class in una directory con controllo delle versioni contiene requisiti aggiuntivi pubblici
-error.versioned.info.requires.added=module-info.class in una directory con controllo delle versioni contiene requisiti aggiuntivi
-error.versioned.info.requires.dropped=Requisiti mancanti in module-info.class in una directory con controllo delle versioni
-error.versioned.info.exports.notequal=module-info.class in una directory con controllo delle versioni contiene esportazioni differenti
-error.versioned.info.provides.notequal=module-info.class in una directory con controllo delle versioni contiene elementi differenti
+error.versioned.info.requires.public=module-info.class in una directory con controllo delle versioni contiene valori "requires public" aggiuntivi
+error.versioned.info.requires.added=module-info.class in una directory con controllo delle versioni contiene valori "requires" aggiuntivi
+error.versioned.info.requires.dropped=module-info.class in una directory con controllo delle versioni contiene valori "requires" mancanti
+error.versioned.info.exports.notequal=module-info.class in una directory con controllo delle versioni contiene "exports" differenti
+error.versioned.info.provides.notequal=module-info.class in una directory con controllo delle versioni contiene valori "provides" differenti
 error.invalid.versioned.module.attribute=Attributo descrittore del modulo {0} non valido.
 error.missing.provider=Provider di servizi non trovato: {0}
 error.release.value.notnumber=release {0} non valida
 error.release.value.toosmall=la release {0} non \u00E8 valida: deve essere >= 9
+error.validator.jarfile.exception=impossibile convalidare {0}: {1}
+error.validator.jarfile.invalid=file jar {0} con pi\u00F9 release non valido eliminato
+error.validator.bad.entry.name=nome di voce {0} con formato non valido
+error.validator.version.notnumber=il nome di voce {0} non dispone di un numero di versione
+error.validator.entryname.tooshort=nome di voce {0} troppo breve. Non \u00E8 una directory
+error.validator.isolated.nested.class=la voce {0} \u00E8 una classe nidificata isolata
+error.validator.new.public.class=la voce {0} contiene una nuova classe pubblica non trovata nelle voci di base
+error.validator.incompatible.class.version=la voce {0} ha una versione incompatibile con una versione precedente
+error.validator.different.api=la voce {0} contiene una classe con un''API diversa dalla versione precedente
+error.validator.names.mismatch=la voce {0} contiene una classe con nome interno {1}. I nomi non corrispondono
+warn.validator.identical.entry=avvertenza: la voce {0} contiene una classe identica a una voce gi\u00E0 presente nel file jar
+warn.validator.resources.with.same.name=avvertenza: voce {0}. Pi\u00F9 risorse con lo stesso nome
+warn.validator.concealed.public.class=avvertenza: la voce {0} \u00E8 una classe pubblica in un package nascosto. \nIl posizionamento di questo file jar nel classpath generer\u00E0 interfacce pubbliche incompatibili
 out.added.manifest=aggiunto manifest
 out.added.module-info=aggiunto module-info: {0}
 out.update.manifest=aggiornato manifest
@@ -68,7 +81,7 @@
 
 usage.compat=Interfaccia di compatibilit\u00E0:\nUso: jar {ctxui}[vfmn0PMe] [file-jar] [file-manifest] [punto di ingresso] [-C dir] file] ...\nOpzioni:\n    -c  crea un nuovo archivio\n    -t  visualizza l'indice dell'archivio\n    -x  estrae i file con nome (o tutti i file) dall'archivio\n    -u  aggiorna l'archivio esistente\n    -v  genera output commentato dall'output standard\n    -f  specifica il nome file dell'archivio\n    -m  include informazioni manifest dal file manifest specificato\n    -n  esegue la normalizzazione Pack200 dopo la creazione di un nuovo archivio\n    -e  specifica il punto di ingresso per l'applicazione stand-alone \n        inclusa nel file jar eseguibile\n    -0  solo memorizzazione; senza compressione ZIP\n    -P  conserva i componenti iniziali '/' (percorso assoluto) e \\"..\\" (directory padre) dai nomi file\n    -M  consente di non creare un file manifest per le voci\n    -i  genera informazioni sull'indice per i file jar specificati\n    -C  imposta la directory specificata e include il file seguente\nSe un file \u00E8 una directory, verr\u00E0 elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di ingresso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' ed 'e'.\n\nEsempio 1: archiviazione di due file di classe in un archivio con il nome classes.jar: \n       jar cvf classes.jar Foo.class Bar.class \nEsempio 2: utilizzo del file manifest esistente 'mymanifest' e archiviazione di tutti i\n           file della directory foo/ in 'classes.jar': \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: \u00E8 necessario specificare una delle opzioni -ctxui.
+main.usage.summary=Uso: jar [OPTION...] [ [--release VERSION] [-C dir] file] ...
 main.usage.summary.try=Utilizzare 'jar --help' per ulteriori informazioni.
 
 main.help.preopt=Uso: jar [OPTION...] [ [--release VERSION] [-C dir] file] ...\nIl file jar crea un archivio per le classi e le risorse e pu\u00F2 manipolare o\nripristinare le singole classi o risorse da un archivio.\n\n Esempi:\n # Crea un archivio denominato classes.jar con due file di classe:\n jar --create --file classes.jar Foo.class Bar.class\n # Crea un archivio mediante un file manifest esistente, con tutti i file in foo/:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # Crea un archivio jar modulare, in cui il descrittore di modulo si trova in\n # classes/module-info.class:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # Aggiorna un file jar non modulare esistente in un file jar modulare:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # Crea un file jar per pi\u00F9 release, posizionando alcuni file nella directory META-INF/versions/9:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 Visualizza l'indice dell'archivio
 main.help.opt.main.update=\  -u, --update               Aggiorna un archivio jar esistente
 main.help.opt.main.extract=\  -x, --extract              Estrae i file con nome (o tutti i file) dall'archivio
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  Stampa il descrittore del modulo
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  Stampa il descrittore del modulo
 main.help.opt.any=\ Modificatori di funzionamento validi in qualsiasi modalit\u00E0:\n\n  -C DIR                     Passa alla directory specificata e include il\n                              file seguente
 main.help.opt.any.file=\  -f, --file=FILE            Il nome file dell'archivio.\n      --release VERSION      Inserisce tutti i file riportati di seguito in una directory con\n                             controllo delle versioni del file JAR (ovvero META-INF/versions/VERSION/).
 main.help.opt.any.verbose=\  -v, --verbose              Genera l'output descrittivo nell'output standard
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          Non crea un file manifest per le voci
 main.help.opt.create.update.module-version=\      --module-version=VERSION    Versione del modulo utilizzata durante la creazione di un file\n                             jar modulare o l'aggiornamento di un file jar non modulare
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN Calcola e registra gli hash dei moduli \n                             corrispondenti in base al pattern specificato e dipendenti\n                             in modo diretto o indiretto dalla creazione di un file jar modulare\n                             o dall'aggiornamento di un file jar non modulare
-main.help.opt.create.update.modulepath=\      --modulepath           Posizione della dipendenza del modulo per la generazione
-\                             dell'hash
+main.help.opt.create.update.module-path=\  -p, --module-path          Posizione della dipendenza del modulo per la generazione\n                             dell'hash
 main.help.opt.create.update.index=\ Modificatori di funzionamento validi solo nella modalit\u00E0 di creazione, aggiornamento e di generazione dell'indice:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          Solo per la memorizzazione. Non utilizza alcuna compressione ZIP
 main.help.opt.other=\ Altre opzioni:\n
 main.help.opt.other.help=\  -?, --help[:compat]        Fornisce questa Guida o facoltativamente la Guida sulla compatibilit\u00E0
 main.help.opt.other.version=\      --version              Stampa la versione del programma
-main.help.postopt=\ Un archivio \u00E8 un file jar modulare se un descrittore di modulo, 'module-info.class', si trova\n nella directory radice delle directory specificate o nella radice dell'archivio jar\n stesso. Le operazioni seguenti sono valide solo durante la creazione di un jar modulare\n o l'aggiornamento di un file jar non modulare esistente: '--module-version',\n '--hash-modules' e '--modulepath'.\n\n Gli argomenti obbligatori o facoltativi per le opzioni lunghe sono obbligatori\n  o facoltativi anche per le opzioni brevi corrispondenti.
+main.help.postopt=\ Un archivio \u00E8 un file jar modulare se un descrittore di modulo, 'module-info.class', si trova\n nella directory radice delle directory specificate o nella radice dell'archivio jar\n stesso. Le operazioni seguenti sono valide solo durante la creazione di un file jar modulare\n o l'aggiornamento di un file jar non modulare esistente: '--module-version',\n '--hash-modules' e '--module-path'.\n\n Gli argomenti obbligatori o facoltativi per le opzioni lunghe sono obbligatori\n  o facoltativi anche per le opzioni brevi corrispondenti.
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=\u8907\u6570\u306E'-cuxti'\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093
+error.multiple.main.operations=\u8907\u6570\u306E'-cuxtid'\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093
 error.cant.open={0}\u3092\u958B\u304F\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
 error.illegal.option=\u4E0D\u6B63\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
 error.unrecognized.option=\u8A8D\u8B58\u3055\u308C\u306A\u3044\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
@@ -42,17 +42,30 @@
 error.module.options.without.info=--module-version\u307E\u305F\u306F--hash-modules\u306E\u3044\u305A\u308C\u304B\u3067module-info.class\u304C\u3042\u308A\u307E\u305B\u3093
 error.unexpected.module-info=\u4E88\u671F\u3057\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF{0}
 error.module.descriptor.not.found=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-error.versioned.info.without.root=module-info.class\u304C\u3001\u30EB\u30FC\u30C8\u306Bmodule-info.class\u306E\u306A\u3044\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u898B\u3064\u304B\u308A\u307E\u3057\u305F
-error.versioned.info.name.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B63\u3057\u304F\u306A\u3044\u540D\u524D\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.requires.public=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306Erequires public\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.requires.added=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306Erequires\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.requires.dropped=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B20\u843D\u3057\u3066\u3044\u308Brequires\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.exports.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308Bexports\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.provides.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308Bprovides\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.versioned.info.without.root=module-info.class\u304C\u3001\u30EB\u30FC\u30C8\u306Bmodule-info.class\u306E\u306A\u3044\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u898B\u3064\u304B\u308A\u307E\u3057\u305F
+error.versioned.info.name.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B63\u3057\u304F\u306A\u3044\u540D\u524D\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.versioned.info.requires.public=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306E"requires public"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.versioned.info.requires.added=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306E"requires"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.versioned.info.requires.dropped=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B20\u843D\u3057\u3066\u3044\u308B"requires"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.versioned.info.exports.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308B"exports"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.versioned.info.provides.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308B"provides"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
 error.invalid.versioned.module.attribute=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u5C5E\u6027{0}\u304C\u7121\u52B9\u3067\u3059
 error.missing.provider=\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}
 error.release.value.notnumber=\u30EA\u30EA\u30FC\u30B9{0}\u306F\u6709\u52B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093
 error.release.value.toosmall=\u30EA\u30EA\u30FC\u30B9{0}\u306F\u6709\u52B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u30029\u4EE5\u4E0A\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
+error.validator.jarfile.exception={0}\u3092\u691C\u8A3C\u3067\u304D\u307E\u305B\u3093: {1}
+error.validator.jarfile.invalid=\u7121\u52B9\u306A\u30DE\u30EB\u30C1\u30EA\u30EA\u30FC\u30B9jar\u30D5\u30A1\u30A4\u30EB{0}\u304C\u524A\u9664\u3055\u308C\u307E\u3057\u305F
+error.validator.bad.entry.name=\u30A8\u30F3\u30C8\u30EA\u540D\u304C\u4E0D\u6B63\u3067\u3059: {0}
+error.validator.version.notnumber=\u30A8\u30F3\u30C8\u30EA\u540D: {0}\u306B\u30D0\u30FC\u30B8\u30E7\u30F3\u756A\u53F7\u304C\u3042\u308A\u307E\u305B\u3093
+error.validator.entryname.tooshort=\u30A8\u30F3\u30C8\u30EA\u540D: {0}\u304C\u77ED\u3059\u304E\u307E\u3059\u3002\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u306F\u3042\u308A\u307E\u305B\u3093
+error.validator.isolated.nested.class=\u30A8\u30F3\u30C8\u30EA: {0}\u306F\u3001\u5206\u96E2\u578B\u306E\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30AF\u30E9\u30B9\u3067\u3059
+error.validator.new.public.class=\u30A8\u30F3\u30C8\u30EA: {0}\u306B\u306F\u3001\u30D9\u30FC\u30B9\u30FB\u30A8\u30F3\u30C8\u30EA\u306B\u5B58\u5728\u3057\u306A\u3044\u65B0\u3057\u3044public\u30AF\u30E9\u30B9\u304C\u542B\u307E\u308C\u307E\u3059
+error.validator.incompatible.class.version=\u30A8\u30F3\u30C8\u30EA: {0}\u306B\u306F\u3001\u4EE5\u524D\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3068\u4E92\u63DB\u6027\u306E\u306A\u3044\u30AF\u30E9\u30B9\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u304C\u542B\u307E\u308C\u307E\u3059
+error.validator.different.api=\u30A8\u30F3\u30C8\u30EA: {0}\u306B\u306F\u3001\u4EE5\u524D\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3068\u306F\u7570\u306A\u308BAPI\u3092\u6301\u3064\u30AF\u30E9\u30B9\u304C\u542B\u307E\u308C\u307E\u3059
+error.validator.names.mismatch=\u30A8\u30F3\u30C8\u30EA: {0}\u306B\u306F\u3001\u5185\u90E8\u540D{1}\u3092\u6301\u3064\u30AF\u30E9\u30B9\u304C\u542B\u307E\u308C\u307E\u3059\u304C\u3001\u540D\u524D\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093
+warn.validator.identical.entry=\u8B66\u544A - \u30A8\u30F3\u30C8\u30EA: {0}\u306B\u306F\u3001jar\u306B\u3059\u3067\u306B\u5B58\u5728\u3059\u308B\u30A8\u30F3\u30C8\u30EA\u3068\u540C\u3058\u30AF\u30E9\u30B9\u304C\u542B\u307E\u308C\u307E\u3059
+warn.validator.resources.with.same.name=\u8B66\u544A - \u30A8\u30F3\u30C8\u30EA: {0}\u3001\u540C\u3058\u540D\u524D\u3092\u6301\u3064\u8907\u6570\u306E\u30EA\u30BD\u30FC\u30B9
+warn.validator.concealed.public.class=\u8B66\u544A - \u30A8\u30F3\u30C8\u30EA{0}\u306F\u3001\u96A0\u3057\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306Epublic\u30AF\u30E9\u30B9\u3067\u3059\u3002 \n\u30AF\u30E9\u30B9\u30D1\u30B9\u306B\u3053\u306Ejar\u3092\u914D\u7F6E\u3059\u308B\u3068\u3001\u4E92\u63DB\u6027\u306E\u306A\u3044public\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u304C\u751F\u6210\u3055\u308C\u307E\u3059
 out.added.manifest=\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F
 out.added.module-info=module-info\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F: {0}
 out.update.manifest=\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u66F4\u65B0\u3055\u308C\u307E\u3057\u305F
@@ -68,7 +81,7 @@
 
 usage.compat=\u4E92\u63DB\u6027\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9:\n\u4F7F\u7528\u65B9\u6CD5: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files] ...\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n    -c  \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B\n    -t  \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3059\u308B\n    -x  \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3059\u308B\n    -u  \u65E2\u5B58\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3059\u308B\n    -v  \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n    -f  \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n    -m  \u6307\u5B9A\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u60C5\u5831\u3092\u53D6\u308A\u8FBC\u3080\n    -n  \u65B0\u898F\u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u4F5C\u6210\u5F8C\u306BPack200\u6B63\u898F\u5316\u3092\u5B9F\u884C\u3059\u308B\n    -e  \u5B9F\u884C\u53EF\u80FDjar\u30D5\u30A1\u30A4\u30EB\u306B\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\n        \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\u3059\u308B\n    -0  \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u306A\u3044\n    -P  \u30D5\u30A1\u30A4\u30EB\u540D\u306E\u5148\u982D\u306E'/' (\u7D76\u5BFE\u30D1\u30B9)\u304A\u3088\u3073\\"..\\" (\u89AA\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA)\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u3092\u4FDD\u6301\u3059\u308B\n    -M  \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u306A\u3044\n    -i  \u6307\u5B9A\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306E\u7D22\u5F15\u60C5\u5831\u3092\u751F\u6210\u3059\u308B\n    -C  \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u6B21\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u308A\u8FBC\u3080\n\u30D5\u30A1\u30A4\u30EB\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u5834\u5408\u306F\u518D\u5E30\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\n\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u540D\u306F\u3001\n\u30D5\u30E9\u30B0'm'\u3001'f'\u3001'e'\u306E\u6307\u5B9A\u3068\u540C\u3058\u9806\u756A\u3067\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u4F8B1: 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6classes.jar\u306B\u4FDD\u5B58\u3059\u308B: \n       jar cvf classes.jar Foo.class Bar.class \n\u4F8B2: \u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB'mymanifest'\u3092\u4F7F\u7528\u3057\u3001foo/\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\n           \u5168\u30D5\u30A1\u30A4\u30EB\u3092'classes.jar'\u306B\u30A2\u30FC\u30AB\u30A4\u30D6\u3059\u308B: \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: \u3044\u305A\u308C\u304B\u306E-ctxui\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
+main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=\u8A73\u7D30\u306F\u3001`jar --help'\u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 
 main.help.preopt=\u4F7F\u7528\u65B9\u6CD5: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar\u306F\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u306E\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u4F5C\u6210\u3057\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u500B\u3005\u306E\u30AF\u30E9\u30B9\u307E\u305F\u306F\n\u30EA\u30BD\u30FC\u30B9\u3092\u64CD\u4F5C\u307E\u305F\u306F\u5FA9\u5143\u3067\u304D\u307E\u3059\u3002\n\n \u4F8B:\n # 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3080classes.jar\u3068\u3044\u3046\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u4F5C\u6210\u3059\u308B:\n jar --create --file classes.jar Foo.class Bar.class\n # foo/\u306E\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3080\u3001\u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u3092\u4F7F\u7528\u3057\u305F\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u4F5C\u6210\u3059\u308B:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # \u30E2\u30B8\u30E5\u30E9jar\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u4F5C\u6210\u3059\u308B\u3002\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u306Fclasses/module-info.class\u306B\n # \u3042\u308B:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # \u65E2\u5B58\u306E\u975E\u30E2\u30B8\u30E5\u30E9jar\u3092\u30E2\u30B8\u30E5\u30E9jar\u306B\u66F4\u65B0\u3059\u308B:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # \u8907\u6570\u30EA\u30EA\u30FC\u30B9jar\u3092\u4F5C\u6210\u3057\u3001\u4E00\u90E8\u306E\u30D5\u30A1\u30A4\u30EB\u3092META-INF/versions/9\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u914D\u7F6E\u3059\u308B:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,9 +91,9 @@
 main.help.opt.main.list=\  -t\u3001--list                 \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3057\u307E\u3059
 main.help.opt.main.update=\  -u\u3001--update               \u65E2\u5B58\u306Ejar\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3057\u307E\u3059
 main.help.opt.main.extract=\  -x\u3001--extract              \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3057\u307E\u3059
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u3092\u51FA\u529B\u3057\u307E\u3059
+main.help.opt.main.print-module-descriptor=\  -d\u3001--print-module-descriptor  \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u3092\u51FA\u529B\u3057\u307E\u3059
 main.help.opt.any=\ \u3069\u306E\u30E2\u30FC\u30C9\u3067\u3082\u6709\u52B9\u306A\u64CD\u4F5C\u4FEE\u98FE\u5B50:\n\n  -C DIR                     \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u6B21\u306E\u30D5\u30A1\u30A4\u30EB\u3092\n                             \u53D6\u308A\u8FBC\u307F\u307E\u3059
-main.help.opt.any.file=\  -f\u3001--file=FILE            \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\n      --release VERSION      \u6B21\u306E\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u3092jar\u306E\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n                             (\u3064\u307E\u308A\u3001META-INF/versions/VERSION/)\u306B\u914D\u7F6E\u3057\u307E\u3059
+main.help.opt.any.file=\  -f\u3001--file=FILE            \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\n      --release VERSION      \u6B21\u306E\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u3092jar\u306E\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n                             (\u3064\u307E\u308A\u3001META-INF/versions/VERSION/)\u306B\u914D\u7F6E\u3057\u307E\u3059
 main.help.opt.any.verbose=\  -v\u3001--verbose              \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3057\u307E\u3059
 main.help.opt.create.update=\ \u4F5C\u6210\u307E\u305F\u306F\u66F4\u65B0\u30E2\u30FC\u30C9\u3067\u306E\u307F\u6709\u52B9\u306A\u64CD\u4F5C\u4FEE\u98FE\u5B50:\n
 main.help.opt.create.update.main-class=\  -e\u3001--main-class=CLASSNAME \u30E2\u30B8\u30E5\u30E9\u307E\u305F\u306F\u5B9F\u884C\u53EF\u80FD\u306Ajar\u30A2\u30FC\u30AB\u30A4\u30D6\u306B\n                             \u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\n                             \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M\u3001--no-manifest          \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u307E\u305B\u3093
 main.help.opt.create.update.module-version=\      --module-version=VERSION    \u30E2\u30B8\u30E5\u30E9jar\u306E\u4F5C\u6210\u6642\u307E\u305F\u306F\u975E\u30E2\u30B8\u30E5\u30E9jar\u306E\u66F4\u65B0\u6642\u306E\n                             \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN \u30E2\u30B8\u30E5\u30E9jar\u306E\u4F5C\u6210\u6642\u307E\u305F\u306F\u975E\u30E2\u30B8\u30E5\u30E9jar\u306E\u66F4\u65B0\u6642\u306B\n                             \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3057\u3001\u76F4\u63A5\u307E\u305F\u306F\u9593\u63A5\u7684\u306B\n                             \u4F9D\u5B58\u3057\u3066\u3044\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30CF\u30C3\u30B7\u30E5\u3092\n                             \u8A08\u7B97\u304A\u3088\u3073\u8A18\u9332\u3057\u307E\u3059
-main.help.opt.create.update.modulepath=\      --modulepath           \u751F\u6210\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u4F9D\u5B58\u6027\u306E\u5834\u6240
-\                             \u30CF\u30C3\u30B7\u30E5
+main.help.opt.create.update.module-path=\  -p\u3001--module-path          \u30CF\u30C3\u30B7\u30E5\u3092\u751F\u6210\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u4F9D\u5B58\u6027\n                             \u306E\u5834\u6240
 main.help.opt.create.update.index=\ \u4F5C\u6210\u3001\u66F4\u65B0\u304A\u3088\u3073\u7D22\u5F15\u751F\u6210\u30E2\u30FC\u30C9\u3067\u306E\u307F\u6709\u52B9\u306A\u64CD\u4F5C\u4FEE\u98FE\u5B50:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u307E\u305B\u3093
 main.help.opt.other=\ \u305D\u306E\u4ED6\u306E\u30AA\u30D7\u30B7\u30E7\u30F3:\n
 main.help.opt.other.help=\  -?, --help[:compat]        \u3053\u308C(\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u4E92\u63DB\u6027)\u3092help\u306B\u6307\u5B9A\u3057\u307E\u3059
 main.help.opt.other.version=\      --version              \u30D7\u30ED\u30B0\u30E9\u30E0\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u307E\u3059
-main.help.postopt=\ \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF'module-info.class'\u304C\u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30EB\u30FC\u30C8\u307E\u305F\u306F\n jar\u30A2\u30FC\u30AB\u30A4\u30D6\u81EA\u4F53\u306E\u30EB\u30FC\u30C8\u306B\u3042\u308B\u5834\u5408\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u306F\u30E2\u30B8\u30E5\u30E9jar\u3067\u3059\u3002\n \u6B21\u306E\u64CD\u4F5C\u306F\u3001\u30E2\u30B8\u30E5\u30E9jar\u306E\u4F5C\u6210\u6642\u307E\u305F\u306F\u65E2\u5B58\u306E\u975E\u30E2\u30B8\u30E5\u30E9jar\u306E\u66F4\u65B0\u6642\u306B\n \u306E\u307F\u6709\u52B9\u3067\u3059:  '--module-version'\u3001\n '--hash-modules'\u304A\u3088\u3073'--modulepath'\u3002\n\n \u30ED\u30F3\u30B0\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3078\u306E\u5FC5\u9808\u307E\u305F\u306F\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u306F\u3001\u5BFE\u5FDC\u3059\u308B\u30B7\u30E7\u30FC\u30C8\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\n \u306B\u5BFE\u3057\u3066\u3082\u5FC5\u9808\u307E\u305F\u306F\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306A\u308A\u307E\u3059\u3002
+main.help.postopt=\ \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF'module-info.class'\u304C\u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30EB\u30FC\u30C8\u307E\u305F\u306F\n jar\u30A2\u30FC\u30AB\u30A4\u30D6\u81EA\u4F53\u306E\u30EB\u30FC\u30C8\u306B\u3042\u308B\u5834\u5408\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u306F\u30E2\u30B8\u30E5\u30E9jar\u3067\u3059\u3002\n \u6B21\u306E\u64CD\u4F5C\u306F\u3001\u30E2\u30B8\u30E5\u30E9jar\u306E\u4F5C\u6210\u6642\u307E\u305F\u306F\u65E2\u5B58\u306E\u975E\u30E2\u30B8\u30E5\u30E9jar\u306E\u66F4\u65B0\u6642\u306B\n \u306E\u307F\u6709\u52B9\u3067\u3059:  '--module-version'\u3001\n '--hash-modules'\u304A\u3088\u3073'--module-path'\u3002\n\n \u30ED\u30F3\u30B0\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3078\u306E\u5FC5\u9808\u307E\u305F\u306F\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u306F\u3001\u5BFE\u5FDC\u3059\u308B\u30B7\u30E7\u30FC\u30C8\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\n \u306B\u5BFE\u3057\u3066\u3082\u5FC5\u9808\u307E\u305F\u306F\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306A\u308A\u307E\u3059\u3002
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ko.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ko.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations='-cuxti' \uC635\uC158\uC744 \uC5EC\uB7EC \uAC1C \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+error.multiple.main.operations='-cuxtid' \uC635\uC158\uC744 \uC5EC\uB7EC \uAC1C \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
 error.cant.open=\uC5F4 \uC218 \uC5C6\uC74C: {0}
 error.illegal.option=\uC798\uBABB\uB41C \uC635\uC158: {0}
 error.unrecognized.option=\uC778\uC2DD\uD560 \uC218 \uC5C6\uB294 \uC635\uC158: {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=\uBAA8\uB4C8 \uAE30\uC220\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC74C
 error.versioned.info.without.root=\uB8E8\uD2B8\uC5D0\uC11C module-info.class \uC5C6\uC774 \uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C module-info.class\uAC00 \uBC1C\uACAC\uB428
 error.versioned.info.name.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uC798\uBABB\uB41C \uC774\uB984\uC774 \uD3EC\uD568\uB428
-error.versioned.info.requires.public=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 \uD544\uC218 \uACF5\uC6A9 \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.requires.added=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 \uD544\uC218 \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.requires.dropped=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB204\uB77D\uB41C \uD544\uC218 \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.exports.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 \uC775\uC2A4\uD3EC\uD2B8 \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.provides.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 \uC81C\uACF5 \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.versioned.info.requires.public=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 "requires public" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.versioned.info.requires.added=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 "requires" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.versioned.info.requires.dropped=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB204\uB77D\uB41C "requires" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.versioned.info.exports.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 "exports" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.versioned.info.provides.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 "provides" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
 error.invalid.versioned.module.attribute=\uBD80\uC801\uD569\uD55C \uBAA8\uB4C8 \uAE30\uC220\uC790 \uC18D\uC131 {0}
 error.missing.provider=\uC11C\uBE44\uC2A4 \uC81C\uACF5\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC74C: {0}
 error.release.value.notnumber=\uB9B4\uB9AC\uC2A4 {0}\uC774(\uAC00) \uBD80\uC801\uD569\uD568
 error.release.value.toosmall=\uB9B4\uB9AC\uC2A4 {0}\uC774(\uAC00) \uBD80\uC801\uD569\uD568. 9 \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.
+error.validator.jarfile.exception={0}\uC744(\uB97C) \uAC80\uC99D\uD560 \uC218 \uC5C6\uC74C: {1}
+error.validator.jarfile.invalid=\uBD80\uC801\uD569\uD55C \uB2E4\uC911 \uB9B4\uB9AC\uC2A4 jar \uD30C\uC77C {0}\uC774(\uAC00) \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
+error.validator.bad.entry.name=\uD56D\uBAA9 \uC774\uB984 \uD615\uC2DD\uC774 \uC798\uBABB\uB428, {0}
+error.validator.version.notnumber=\uD56D\uBAA9 \uC774\uB984 {0}\uC5D0 \uBC84\uC804 \uBC88\uD638\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
+error.validator.entryname.tooshort=\uD56D\uBAA9 \uC774\uB984 {0}\uC774(\uAC00) \uB108\uBB34 \uC9E7\uACE0 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4.
+error.validator.isolated.nested.class={0} \uD56D\uBAA9\uC740 \uBD84\uB9AC\uB41C \uC911\uCCA9 \uD074\uB798\uC2A4\uC785\uB2C8\uB2E4.
+error.validator.new.public.class={0} \uD56D\uBAA9\uC5D0 \uAE30\uBCF8 \uD56D\uBAA9\uC5D0\uC11C \uCC3E\uC744 \uC218 \uC5C6\uB294 \uC0C8\uB85C\uC6B4 \uACF5\uC6A9 \uD074\uB798\uC2A4\uAC00 \uC788\uC2B5\uB2C8\uB2E4.
+error.validator.incompatible.class.version={0} \uD56D\uBAA9\uC5D0 \uC774\uC804 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uD074\uB798\uC2A4 \uBC84\uC804\uC774 \uC788\uC2B5\uB2C8\uB2E4.
+error.validator.different.api={0} \uD56D\uBAA9\uC5D0 \uC774\uC804 \uBC84\uC804\uACFC \uB2E4\uB978 api\uB97C \uAC00\uC9C4 \uD074\uB798\uC2A4\uAC00 \uC788\uC2B5\uB2C8\uB2E4.
+error.validator.names.mismatch={0} \uD56D\uBAA9\uC5D0 \uB0B4\uBD80 \uC774\uB984 {1}\uC744(\uB97C) \uAC00\uC9C4 \uD074\uB798\uC2A4\uAC00 \uC788\uC9C0\uB9CC \uC774\uB984\uC774 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
+warn.validator.identical.entry=\uACBD\uACE0 - {0} \uD56D\uBAA9\uC5D0 \uC774\uBBF8 jar\uC5D0 \uC788\uB294 \uD56D\uBAA9\uACFC \uB3D9\uC77C\uD55C \uD074\uB798\uC2A4\uAC00 \uC788\uC2B5\uB2C8\uB2E4.
+warn.validator.resources.with.same.name=\uACBD\uACE0 - {0} \uD56D\uBAA9\uC5D0 \uB3D9\uC77C\uD55C \uC774\uB984\uC758 \uC5EC\uB7EC \uB9AC\uC18C\uC2A4\uAC00 \uC788\uC2B5\uB2C8\uB2E4.
+warn.validator.concealed.public.class=\uACBD\uACE0 - {0} \uD56D\uBAA9\uC740 \uC228\uACA8\uC9C4 \uD328\uD0A4\uC9C0\uC5D0 \uC788\uB294 \uACF5\uC6A9 \uD074\uB798\uC2A4\uC785\uB2C8\uB2E4. \n\uC774 jar\uB97C \uD074\uB798\uC2A4 \uACBD\uB85C\uC5D0 \uBC30\uCE58\uD558\uBA74 \uACF5\uC6A9 \uC778\uD130\uD398\uC774\uC2A4\uAC00 \uD638\uD658\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
 out.added.manifest=Manifest\uB97C \uCD94\uAC00\uD568
 out.added.module-info=\uCD94\uAC00\uB41C \uBAA8\uB4C8 \uC815\uBCF4: {0}
 out.update.manifest=Manifest\uB97C \uC5C5\uB370\uC774\uD2B8\uD568
@@ -68,7 +81,7 @@
 
 usage.compat=\uD638\uD658\uC131 \uC778\uD130\uD398\uC774\uC2A4:\n\uC0AC\uC6A9\uBC95: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\uC635\uC158:\n    -c  \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n    -t  \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.\n    -x  \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.\n    -u  \uAE30\uC874 \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n    -v  \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n    -f  \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n    -m  \uC9C0\uC815\uB41C Manifest \uD30C\uC77C\uC758 Manifest \uC815\uBCF4\uB97C \uD3EC\uD568\uD569\uB2C8\uB2E4.\n    -n  \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD55C \uD6C4 Pack200 \uC815\uADDC\uD654\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n    -e  jar \uC2E4\uD589 \uD30C\uC77C\uC5D0 \uBC88\uB4E4\uB85C \uC81C\uACF5\uB41C \uB3C5\uB9BD\uD615 \uC560\uD50C\uB9AC\uCF00\uC774\uC158\uC758 \n        \uC560\uD50C\uB9AC\uCF00\uC774\uC158 \uC2DC\uC791 \uC9C0\uC810\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n    -0  \uC800\uC7A5 \uC804\uC6A9\uC774\uBA70 ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n    -P  \uD30C\uC77C \uC774\uB984\uC5D0\uC11C \uC120\uD589 '/'(\uC808\uB300 \uACBD\uB85C) \uBC0F ".."(\uC0C1\uC704 \uB514\uB809\uD1A0\uB9AC) \uAD6C\uC131\uC694\uC18C\uB97C \uC720\uC9C0\uD569\uB2C8\uB2E4.\n    -M  \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n    -i  \uC9C0\uC815\uB41C jar \uD30C\uC77C\uC5D0 \uB300\uD55C \uC778\uB371\uC2A4 \uC815\uBCF4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n    -C  \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744 \uD3EC\uD568\uD569\uB2C8\uB2E4.\n\uD2B9\uC815 \uD30C\uC77C\uC774 \uB514\uB809\uD1A0\uB9AC\uC77C \uACBD\uC6B0 \uC21C\uD658\uC801\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.\nManifest \uD30C\uC77C \uC774\uB984, \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984 \uBC0F \uC2DC\uC791 \uC9C0\uC810 \uC774\uB984\uC740\n'm', 'f' \uBC0F 'e' \uD50C\uB798\uADF8\uC640 \uB3D9\uC77C\uD55C \uC21C\uC11C\uB85C \uC9C0\uC815\uB429\uB2C8\uB2E4.\n\n\uC608 1: classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n       jar cvf classes.jar Foo.class Bar.class \n\uC608 2: \uAE30\uC874 Manifest \uD30C\uC77C 'mymanifest'\uB97C \uC0AC\uC6A9\uD558\uC5EC\n           foo/ \uB514\uB809\uD1A0\uB9AC\uC758 \uBAA8\uB4E0 \uD30C\uC77C\uC744 'classes.jar'\uB85C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: -ctxui \uC635\uC158 \uC911 \uD558\uB098\uB97C \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.
+main.usage.summary=\uC0AC\uC6A9\uBC95: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=\uC790\uC138\uD55C \uB0B4\uC6A9\uC744 \uBCF4\uB824\uBA74 'jar --help'\uB97C \uC2E4\uD589\uD558\uC2ED\uC2DC\uC624.
 
 main.help.preopt=\uC0AC\uC6A9\uBC95: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar\uB294 \uD074\uB798\uC2A4 \uBC0F \uB9AC\uC18C\uC2A4\uC5D0 \uB300\uD55C \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4. \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C\n\uAC1C\uBCC4 \uD074\uB798\uC2A4\uB098 \uB9AC\uC18C\uC2A4\uB97C \uC870\uC791\uD558\uAC70\uB098 \uBCF5\uC6D0\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n\n \uC608\uC81C:\n # \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC0AC\uC6A9\uD558\uC5EC classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C \uC0DD\uC131:\n jar --create --file classes.jar Foo.class Bar.class\n # \uAE30\uC874 Manifest\uB97C \uC0AC\uC6A9\uD558\uC5EC \uBAA8\uB4E0 \uD30C\uC77C\uC774 foo/\uC5D0 \uD3EC\uD568\uB41C \uC544\uCE74\uC774\uBE0C \uC0DD\uC131:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # \uBAA8\uB4C8 \uAE30\uC220\uC790\uAC00 classes/module-info.class\uC5D0 \uC704\uCE58\uD55C\n # \uBAA8\uB4C8\uD615 jar \uC544\uCE74\uC774\uBE0C \uC0DD\uC131:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # \uAE30\uC874 \uBE44\uBAA8\uB4C8 jar\uB97C \uBAA8\uB4C8\uD615 jar\uB85C \uC5C5\uB370\uC774\uD2B8:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # \uC77C\uBD80 \uD30C\uC77C\uC774 META-INF/versions/9 \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC704\uCE58\uD55C \uB2E4\uC911 \uB9B4\uB9AC\uC2A4 jar \uC0DD\uC131:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.
 main.help.opt.main.update=\  -u, --update               \uAE30\uC874 jar \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.
 main.help.opt.main.extract=\  -x, --extract              \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  \uBAA8\uB4C8 \uAE30\uC220\uC790\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  \uBAA8\uB4C8 \uAE30\uC220\uC790\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.
 main.help.opt.any=\ \uBAA8\uB4E0 \uBAA8\uB4DC\uC5D0\uC11C \uC801\uD569\uD55C \uC791\uC5C5 \uC218\uC815\uC790:\n\n  -C DIR                     \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744\n                             \uD3EC\uD568\uD569\uB2C8\uB2E4.
 main.help.opt.any.file=\  -f, --file=FILE            \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC785\uB2C8\uB2E4.\n      --release VERSION      \uB2E4\uC74C \uBAA8\uB4E0 \uD30C\uC77C\uC744 \uBC84\uC804 \uC9C0\uC815\uB41C jar \uB514\uB809\uD1A0\uB9AC\n                             (\uC608: META-INF/versions/VERSION/)\uC5D0 \uBC30\uCE58\uD569\uB2C8\uB2E4.
 main.help.opt.any.verbose=\  -v, --verbose              \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
 main.help.opt.create.update.module-version=\      --module-version=VERSION    \uBAA8\uB4C8\uD615 jar\uB97C \uC0DD\uC131\uD558\uAC70\uB098 \uBE44\uBAA8\uB4C8 jar\uB97C\n                             \uC5C5\uB370\uC774\uD2B8\uD560 \uB54C \uBAA8\uB4C8 \uBC84\uC804\uC785\uB2C8\uB2E4.
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN \uC0DD\uC131 \uC911\uC778 \uBAA8\uB4C8\uD615 jar \uB610\uB294 \uC5C5\uB370\uC774\uD2B8 \uC911\uC778 \uBE44\uBAA8\uB4C8 jar\uC5D0 \n                             \uC9C1\uC811 \uB610\uB294 \uAC04\uC811\uC801\uC73C\uB85C \uC758\uC874\uD558\uACE0 \uC8FC\uC5B4\uC9C4 \uD328\uD134\uACFC \uC77C\uCE58\uD558\uB294\n                             \uBAA8\uB4C8\uC758 \uD574\uC2DC\uB97C \uCEF4\uD4E8\uD2B8\uD558\uACE0\n                             \uAE30\uB85D\uD569\uB2C8\uB2E4.
-main.help.opt.create.update.modulepath=\      --modulepath           \uD574\uC2DC\uB97C \uC0DD\uC131\uD558\uAE30 \uC704\uD55C \uBAA8\uB4C8 \uC885\uC18D\uC131\uC758
-\                             \uC704\uCE58\uC785\uB2C8\uB2E4.
+main.help.opt.create.update.module-path=\  -p, --module-path          \uD574\uC2DC\uB97C \uC0DD\uC131\uD558\uAE30 \uC704\uD55C \uBAA8\uB4C8 \uC885\uC18D\uC131\uC758\n                             \uC704\uCE58\uC785\uB2C8\uB2E4.
 main.help.opt.create.update.index=\ \uC0DD\uC131, \uC5C5\uB370\uC774\uD2B8 \uBC0F generate-index \uBAA8\uB4DC\uC5D0\uC11C\uB9CC \uC801\uD569\uD55C \uC791\uC5C5 \uC218\uC815\uC790:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          \uC800\uC7A5 \uC804\uC6A9\uC774\uBA70 ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
 main.help.opt.other=\ \uAE30\uD0C0 \uC635\uC158:\n
 main.help.opt.other.help=\  -?, --help[:compat]        \uC774 \uB3C4\uC6C0\uB9D0(\uB610\uB294 \uC120\uD0DD\uC801\uC73C\uB85C \uD638\uD658\uC131)\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4.
 main.help.opt.other.version=\      --version              \uD504\uB85C\uADF8\uB7A8 \uBC84\uC804\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.
-main.help.postopt=\ \uC544\uCE74\uC774\uBE0C\uB294 \uBAA8\uB4C8 \uAE30\uC220\uC790 'module-info.class'\uAC00 \uC8FC\uC5B4\uC9C4 \uB514\uB809\uD1A0\uB9AC\uC758\n \uB8E8\uD2B8 \uB610\uB294 jar \uC544\uCE74\uC774\uBE0C \uC790\uCCB4\uC758 \uB8E8\uD2B8\uC5D0 \uC704\uCE58\uD55C \uACBD\uC6B0 \uBAA8\uB4C8\uD615 jar\uC785\uB2C8\uB2E4.\n \uB2E4\uC74C \uC791\uC5C5\uC740 \uBAA8\uB4C8\uD615 jar\uB97C \uC0DD\uC131\uD558\uAC70\uB098 \uAE30\uC874 \uBE44\uBAA8\uB4C8 jar\uB97C\n \uC5C5\uB370\uC774\uD2B8\uD560 \uB54C\uB9CC \uC801\uD569\uD569\uB2C8\uB2E4. '--module-version',\n '--hash-modules' \uBC0F '--modulepath'.\n\n long \uC635\uC158\uC758 \uD544\uC218 \uB610\uB294 \uC120\uD0DD\uC801 \uC778\uC218\uB294 \uD574\uB2F9\uD558\uB294 short \uC635\uC158\uC5D0 \uB300\uD574\uC11C\uB3C4\n \uD544\uC218 \uB610\uB294 \uC120\uD0DD\uC801\uC785\uB2C8\uB2E4.
+main.help.postopt=\ \uC544\uCE74\uC774\uBE0C\uB294 \uBAA8\uB4C8 \uAE30\uC220\uC790 'module-info.class'\uAC00 \uC8FC\uC5B4\uC9C4 \uB514\uB809\uD1A0\uB9AC\uC758\n \uB8E8\uD2B8 \uB610\uB294 jar \uC544\uCE74\uC774\uBE0C \uC790\uCCB4\uC758 \uB8E8\uD2B8\uC5D0 \uC704\uCE58\uD55C \uACBD\uC6B0 \uBAA8\uB4C8\uD615 jar\uC785\uB2C8\uB2E4.\n \uB2E4\uC74C \uC791\uC5C5\uC740 \uBAA8\uB4C8\uD615 jar\uB97C \uC0DD\uC131\uD558\uAC70\uB098 \uAE30\uC874 \uBE44\uBAA8\uB4C8 jar\uB97C\n \uC5C5\uB370\uC774\uD2B8\uD560 \uB54C\uB9CC \uC801\uD569\uD569\uB2C8\uB2E4. '--module-version',\n '--hash-modules' \uBC0F '--module-path'.\n\n long \uC635\uC158\uC758 \uD544\uC218 \uB610\uB294 \uC120\uD0DD\uC801 \uC778\uC218\uB294 \uD574\uB2F9\uD558\uB294 short \uC635\uC158\uC5D0 \uB300\uD574\uC11C\uB3C4\n \uD544\uC218 \uB610\uB294 \uC120\uD0DD\uC801\uC785\uB2C8\uB2E4.
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_pt_BR.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_pt_BR.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=Voc\u00EA n\u00E3o pode especificar mais de uma das op\u00E7\u00F5es '-cuxti'
+error.multiple.main.operations=Voc\u00EA n\u00E3o pode especificar mais de uma das op\u00E7\u00F5es '-cuxtid'
 error.cant.open=n\u00E3o \u00E9 poss\u00EDvel abrir: {0}
 error.illegal.option=Op\u00E7\u00E3o inv\u00E1lida: {0}
 error.unrecognized.option=op\u00E7\u00E3o n\u00E3o reconhecida : {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=Descritor de m\u00F3dulo n\u00E3o encontrado
 error.versioned.info.without.root=module-info.class encontrado em um diret\u00F3rio com controle de vers\u00E3o sem module-info.class na raiz
 error.versioned.info.name.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m nome incorreto
-error.versioned.info.requires.public=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m uma depend\u00EAncia requires public adicional
-error.versioned.info.requires.added=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m uma depend\u00EAncia requires adicional
-error.versioned.info.requires.dropped=em module-info.class em um diret\u00F3rio com controle de vers\u00E3o falta uma depend\u00EAncia requires
-error.versioned.info.exports.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m depend\u00EAncias exports diferentes
-error.versioned.info.provides.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m depend\u00EAncias provides diferentes
+error.versioned.info.requires.public=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "requires public" adicional
+error.versioned.info.requires.added=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "requires" adicional
+error.versioned.info.requires.dropped=module-info.class em um diret\u00F3rio com controle de vers\u00E3o falta "requires"
+error.versioned.info.exports.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "exports" diferente
+error.versioned.info.provides.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "provides" diferente
 error.invalid.versioned.module.attribute=Atributo {0} de descritor de m\u00F3dulo inv\u00E1lido
 error.missing.provider=Prestador de servi\u00E7os  n\u00E3o encontrado: {0}
 error.release.value.notnumber=release {0} n\u00E3o v\u00E1lida
 error.release.value.toosmall=release {0} n\u00E3o v\u00E1lida; deve ser >= 9
+error.validator.jarfile.exception=n\u00E3o \u00E9 poss\u00EDvel validar {0}: {1}
+error.validator.jarfile.invalid=arquivo jar {0} multi-release inv\u00E1lido exclu\u00EDdo
+error.validator.bad.entry.name=nome de entrada incorreto, {0}
+error.validator.version.notnumber=o nome de entrada {0} n\u00E3o tem um n\u00FAmero de vers\u00E3o
+error.validator.entryname.tooshort=nome de entrada {0} muito pequeno, n\u00E3o \u00E9 um diret\u00F3rio
+error.validator.isolated.nested.class=a entrada {0} \u00E9 uma classe aninhada isolada
+error.validator.new.public.class=a entrada {0} cont\u00E9m uma nova classe p\u00FAblica n\u00E3o encontrada nas entradas de base
+error.validator.incompatible.class.version=a entrada {0} tem uma vers\u00E3o de classe incompat\u00EDvel com uma vers\u00E3o anterior
+error.validator.different.api=a entrada {0} cont\u00E9m uma classe com api diferente da vers\u00E3o anterior
+error.validator.names.mismatch=a entrada {0} cont\u00E9m uma classe com o nome interno {1}; os nomes n\u00E3o correspondem
+warn.validator.identical.entry=advert\u00EAncia - a entrada {0} cont\u00E9m uma classe id\u00EAntica a uma que j\u00E1 est\u00E1 no jar
+warn.validator.resources.with.same.name=advert\u00EAncia - entrada {0}; diversos recursos com o mesmo nome
+warn.validator.concealed.public.class=advert\u00EAncia - a entrada {0} \u00E9 uma classe p\u00FAblica em um pacote oculto, \ncolocar esse jar no caminho de classe resultar\u00E1 em interfaces p\u00FAblicas incompat\u00EDveis
 out.added.manifest=manifesto adicionado
 out.added.module-info=module-info: {0} adicionado
 out.update.manifest=manifesto atualizado
@@ -68,7 +81,7 @@
 
 usage.compat=Interface de Compatibilidade:\nUso: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] arquivos] ...\nOp\u00E7\u00F5es:\n    -c  cria novo arquivo compactado\n    -t  lista o sum\u00E1rio do arquivo compactado\n    -x  extrai arquivos com o nome (ou todos) do arquivo compactado\n    -u  atualiza o arquivo compactado existente\n    -v  gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o\n    -f  especifica o nome do arquivo compactado\n    -m  inclui as informa\u00E7\u00F5es do manifesto do arquivo de manifesto especificado\n    -n   executa a normaliza\u00E7\u00E3o Pack200 ap\u00F3s a cria\u00E7\u00E3o de um novo arquivo compactado\n    -e  especifica o ponto de entrada da aplicativo para aplicativo stand-alone \n        empacotada em um arquivo jar execut\u00E1vel\n    -0  armazena somente; n\u00E3o usa compacta\u00E7\u00E3o ZIP\n    -P  preserva os componentes '/' inicial (caminho absoluto) e ".." (diret\u00F3rio pai) nos nomes dos arquivos\n    -M  n\u00E3o cria um arquivo de manifesto para as entradas\n    -i  gera informa\u00E7\u00F5es de \u00EDndice para os arquivos jar especificados\n    -C  passa para o diret\u00F3rio especificado e inclui o arquivo a seguir\nSe um arquivo tamb\u00E9m for um diret\u00F3rio, ele ser\u00E1 processado repetidamente.\nO nome do arquivo de manifesto, o nome do arquivo compactado e o nome do ponto de entrada s\u00E3o\nespecificados na mesma ordem dos flags 'm', 'f' e 'e'.\n\nExemplo 1: para arquivar dois arquivos de classe em um arquivo compactado denominado classes.jar: \n       jar cvf classes.jar Foo.class Bar.class \nExemplo 2: use um arquivo de manifesto existente 'mymanifest' e arquive todos os\n           arquivos no diret\u00F3rio foo/ em 'classes.jar': \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: Voc\u00EA deve especificar uma das op\u00E7\u00F5es -ctxui.
+main.usage.summary=Uso: jar [OPTION...] [ [--release VERSION] [-C dir] arquivos]...
 main.usage.summary.try=Tente `jar --ajuda' para obter mais informa\u00E7\u00F5es.
 
 main.help.preopt=Uso: jar [OPTION...] [ [--release VERSION] [-C dir] arquivos]...\njar cria um arquivo compactado para classes e recursos, e pode manipular ou\nrestaurar classes ou recursos individuais de um arquivo compactado.\n\n Exemplos:\n # Cria um arquivo compactado chamado classes.jar com dois arquivos de classe:\n jar --create --file classes.jar Foo.class Bar.class\n # Cria um arquivo compactado usando um manifesto existente, com todos os arquivos em foo/:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # Cria um arquivo compactado jar modular, em que o descritor do m\u00F3dulo se localize em\n # classes/module-info.class:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # Atualiza um arquivo jar n\u00E3o modular existente para um jar modular:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # Cria um arquivo jar de v\u00E1rias releases, colocando alguns arquivos no diret\u00F3rio META-INF/versions/9:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 Lista o conte\u00FAdo do arquivo compactado
 main.help.opt.main.update=\  -u, --update               Atualiza um arquivo compactado jar existente
 main.help.opt.main.extract=\  -x, --extract              Extrai arquivos nomeados (ou todos) do arquivo compactado
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  Imprime o descritor do m\u00F3dulo
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  Imprimir o descritor de m\u00F3dulo
 main.help.opt.any=\ Modificadores de opera\u00E7\u00E3o v\u00E1lidos em qualquer modo:\n\n  -C DIR                     Altera para o diret\u00F3rio especificado e inclui o\n                             seguinte arquivo:
 main.help.opt.any.file=\  -f, --file=FILE            O nome do arquivo compactado\n      --release VERSION      Coloca todos os arquivos a seguir em um diret\u00F3rio com controle de vers\u00E3o\n                             do arquivo jar (i.e. META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              Gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          N\u00E3o cria um arquivo de manifesto para as entradas
 main.help.opt.create.update.module-version=\      --module-version=VERSION    A vers\u00E3o do m\u00F3dulo, ao criar um arquivo jar\n                             modular, ou atualizar um arquivo jar n\u00E3o modular
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN Calcula e registra os hashes dos m\u00F3dulos\n                             correlacionado pelo padr\u00E3o fornecido e do qual depende\n                             direta ou indiretamente em um arquivo jar modular que est\u00E1 sendo\n                             criado ou em um arquivo jar n\u00E3o modular que est\u00E1 sendo atualizado
-main.help.opt.create.update.modulepath=\      --modulepath           Localiza\u00E7\u00E3o da depend\u00EAncia de m\u00F3dulo para gerar
-\                             o hash
+main.help.opt.create.update.module-path=\  -p, --module-path          Local de depend\u00EAncia de m\u00F3dulo para gerar\n                             o hash
 main.help.opt.create.update.index=\ Modificadores de opera\u00E7\u00E3o v\u00E1lidos somente no modo de cria\u00E7\u00E3o, atualiza\u00E7\u00E3o e gera\u00E7\u00E3o de \u00EDndice:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          Somente armazenamento; n\u00E3o use compacta\u00E7\u00E3o ZIP
 main.help.opt.other=\ Outras op\u00E7\u00F5es:\n
 main.help.opt.other.help=\  -?, --help[:compat]        Fornece esta ajuda ou, opcionalmente, a ajuda de compatibilidade
 main.help.opt.other.version=\      --version              Imprime a vers\u00E3o do programa
-main.help.postopt=\ Um arquivo compactado \u00E9 um arquivo jar modular se um descritor de m\u00F3dulo, 'module-info.class', estiver\n localizado na raiz dos diret\u00F3rios fornecidos, ou na raiz do arquivo compactado jar\n propriamente dito. As seguintes opera\u00E7\u00F5es s\u00F3 s\u00E3o v\u00E1lidas ao criar um arquivo jar modular\n ou atualizar um arquivo jar n\u00E3o modular existente: '--module-version',\n '--hash-modules' e '--modulepath'.\n\n Argumentos obrigat\u00F3rios ou opcionais para op\u00E7\u00F5es longas tamb\u00E9m s\u00E3o obrigat\u00F3rios ou opcionais\n para quaisquer op\u00E7\u00F5es curtas correspondentes.
+main.help.postopt=\ Arquivo compactado ser\u00E1 um arquivo jar modular se um descritor de m\u00F3dulo, 'module-info.class', estiver\n localizado na raiz dos diret\u00F3rios em quest\u00E3o ou na raiz do pr\u00F3prio arquivo compactado\n jar. As seguintes opera\u00E7\u00F5es s\u00F3 s\u00E3o v\u00E1lidas ao criar um jar modular\n ou atualizar um jar n\u00E3o modular existente: '--module-version',\n '--hash-modules' e '--module-path'.\n\n Argumentos obrigat\u00F3rios ou opcionais para op\u00E7\u00F5es longas tamb\u00E9m s\u00E3o obrigat\u00F3rios ou opcionais\n para quaisquer op\u00E7\u00F5es curtas correspondentes.
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_sv.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_sv.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=Du kan inte ange flera -cuxti-alternativ
+error.multiple.main.operations=Du kan inte ange flera -cuxtid-alternativ
 error.cant.open=kan inte \u00F6ppna: {0}
 error.illegal.option=Otill\u00E5tet alternativ: {0}
 error.unrecognized.option=ok\u00E4nt alternativ: {0}
@@ -53,6 +53,19 @@
 error.missing.provider=Tj\u00E4nsteleverant\u00F6ren hittades inte: {0}
 error.release.value.notnumber=utg\u00E5va {0} \u00E4r inte giltig
 error.release.value.toosmall=utg\u00E5va {0} \u00E4r inte giltig, m\u00E5ste vara >= 9
+error.validator.jarfile.exception=kan inte validera {0}: {1}
+error.validator.jarfile.invalid=ogiltig jar-fil f\u00F6r flera utg\u00E5vor, {0}, har tagits bort
+error.validator.bad.entry.name=postnamnet {0} \u00E4r felaktigt utformat
+error.validator.version.notnumber=postnamnet {0} har inget versionsnummer
+error.validator.entryname.tooshort=postnamnet {0} \u00E4r f\u00F6r kort, inte en katalog
+error.validator.isolated.nested.class=posten {0} \u00E4r en isolerad kapslad klass
+error.validator.new.public.class=posten {0} inneh\u00E5ller en ny allm\u00E4n klass som inte kan hittas i basposterna
+error.validator.incompatible.class.version=posten {0} har en klassversion som \u00E4r inkompatibel med en tidigare version
+error.validator.different.api=posten {0} inneh\u00E5ller en klass med ett annat api fr\u00E5n en tidigare version
+error.validator.names.mismatch=posten {0} inneh\u00E5ller en klass med det interna namnet {1}, namnen matchar inte
+warn.validator.identical.entry=varning - posten {0} inneh\u00E5ller en klass som \u00E4r identisk med en post som redan finns i jar-filen
+warn.validator.resources.with.same.name=varning - posten {0}, flera resurser med samma namn
+warn.validator.concealed.public.class=varning - posten {0} \u00E4r en allm\u00E4n klass i ett dolt paket. \nOm du placerar den h\u00E4r jar-filen p\u00E5 klass\u00F6kv\u00E4gen leder det till inkompatibla allm\u00E4nna gr\u00E4nssnitt
 out.added.manifest=tillagt manifestfil
 out.added.module-info=lade till module-info: {0}
 out.update.manifest=uppdaterat manifest
@@ -68,7 +81,7 @@
 
 usage.compat=Kompatibilitetsgr\u00E4nssnitt:\nSyntax: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nAlternativ:\n    -c  skapa nytt arkiv\n    -t  lista inneh\u00E5llsf\u00F6rteckning f\u00F6r arkiv\n    -x  extrahera namngivna (eller alla) filer fr\u00E5n arkivet\n    -u  uppdatera befintligt arkiv\n    -v  generera utf\u00F6rliga utdata till standardutdata\n    -f  ange namnet p\u00E5 arkivfilen\n    -m  inkludera manifestinformation fr\u00E5n den angivna manifestfilen\n    -n  utf\u00F6r Pack200-normalisering n\u00E4r ett nytt arkiv har skapats\n    -e  ange applikationsing\u00E5ngspunkt f\u00F6r frist\u00E5ende applikation \n        som medf\u00F6ljer i en jar-programfil\n    -0  lagra endast, anv\u00E4nd inte ZIP-komprimering\n    -P  beh\u00E5ll komponenter f\u00F6r inledande '/' (absolut s\u00F6kv\u00E4g) och ".." (\u00F6verordnad  katalog) fr\u00E5n filnamn\n    -M  skapa inte en manifestfil f\u00F6r posterna\n    -i  generera indexinformation f\u00F6r de angivna jar-filerna\n    -C  \u00E4ndra till den angivna katalogen och inkludera f\u00F6ljande fil\nOm en fil \u00E4r en katalog bearbetas den rekursivt.\nNamnen p\u00E5 manifestfilen, arkivfilen och ing\u00E5ngspunkten anges med samma\nordning som flaggorna 'm', 'f' och 'e'.\n\nExempel 1: arkivera tv\u00E5 klassfiler i ett arkiv med namnet classes.jar: \n       jar cvf classes.jar Foo.class Bar.class \nExempel 2: anv\u00E4nd den befintliga manifestfilen 'mymanifest' och arkivera alla\n           filer i katalogen 'foo/' till 'classes.jar': \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: du m\u00E5ste ange ett av -ctxui-alternativen.
+main.usage.summary=Syntax: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=F\u00F6rs\u00F6k med 'jar --help' f\u00F6r mer information.
 
 main.help.preopt=Syntax: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar skapar ett arkiv f\u00F6r klasser och resurser, och kan \u00E4ndra och \u00E5terst\u00E4lla\nenskilda klasser och resurser fr\u00E5n ett arkiv.\n\n Exempel:\n # Skapa ett arkiv med namnet classes.jar med tv\u00E5 klassfiler:\n jar --create --file classes.jar Foo.class Bar.class\n # Skapa ett arkiv med ett befintligt manifest med alla filerna i 'foo/':\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # Skapa ett modul\u00E4rt jar-arkiv, d\u00E4r moduldeskriptorn finns i\n # classes/module-info.class:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # Uppdatera ett befintligt icke-modul\u00E4rt jar-arkiv till ett modul\u00E4rt jar-arkiv:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # Skapa ett jar-arkiv f\u00F6r flera utg\u00E5vor och placera vissa av filerna i katalogen 'META-INF/versions/9':\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 Listar inneh\u00E5llsf\u00F6rteckningen f\u00F6r arkivet
 main.help.opt.main.update=\  -u, --update               Uppdatera ett befintligt jar-arkiv
 main.help.opt.main.extract=\  -x, --extract              Extrahera namngivna (eller alla) filer fr\u00E5n arkivet
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  Skriv ut moduldeskriptorn
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  Skriv ut moduldeskriptorn
 main.help.opt.any=\ \u00C5tg\u00E4rdsmodifierare som \u00E4r giltiga i alla l\u00E4gen:\n\n  -C DIR                     \u00C4ndra till den angivna katalogen och inkludera\n                             f\u00F6ljande fil
 main.help.opt.any.file=\  -f, --file=FILE            Namnet p\u00E5 arkivfilen\n      --release VERSION      Placerar alla f\u00F6ljande filer i en versionshanterad katalog\n                             i jar-arkivet (exempel: META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              Generera utf\u00F6rliga utdata till standardutdata
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          Skapa inte en manifestfil f\u00F6r posterna
 main.help.opt.create.update.module-version=\      --module-version=VERSION    Modulversionen vid skapande av ett modul\u00E4rt\n                             jar-arkiv eller vid uppdatering av ett icke-modul\u00E4rt jar-arkiv
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN Ber\u00E4kna och registrera hashningarna f\u00F6r moduler som\n                             matchar det angivna m\u00F6nstret och som \u00E4r direkt eller\n                             indirekt beroende av att ett modul\u00E4rt jar-arkiv skapas\n                             eller att ett icke-modul\u00E4rt jar-arkiv uppdateras
-main.help.opt.create.update.modulepath=\      --modulepath           Plats f\u00F6r modulberoende f\u00F6r att generera
-\                             hashningen
+main.help.opt.create.update.module-path=\  -p, --module-path          Plats f\u00F6r modulberoende f\u00F6r att generera\n                             hashningen
 main.help.opt.create.update.index=\ \u00C5tg\u00E4rdsmodifierare som endast \u00E4r giltiga i l\u00E4gena create, update och generate-index:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          Endast lagring, anv\u00E4nd ingen ZIP-komprimering
 main.help.opt.other=\ \u00D6vriga alternativ:\n
 main.help.opt.other.help=\  -?, --help[:compat]        Visa den h\u00E4r hj\u00E4lpen eller kompatibilitetshj\u00E4lpen (valfritt)
 main.help.opt.other.version=\      --version              Skriv ut programversion
-main.help.postopt=\ Ett arkiv \u00E4r ett modul\u00E4rt jar-arkiv om en moduldeskriptor, 'module-info.class',\n finns i roten av de angivna katalogerna eller det angivna jar-arkivet.\n F\u00F6ljande \u00E5tg\u00E4rder \u00E4r endast giltiga vid skapande av ett modul\u00E4rt jar-arkiv och\n vid uppdatering av ett befintligt icke-modul\u00E4rt jar-arkiv: '--module-version',\n '--hash-modules' och '--modulepath'.\n\n Obligatoriska och valfria alternativ f\u00F6r l\u00E5nga alternativ \u00E4r \u00E4ven obligatoriska\n respektive valfria f\u00F6r alla motsvarande korta alternativ.
+main.help.postopt=\ Ett arkiv \u00E4r ett modul\u00E4rt jar-arkiv om en moduldeskriptor, 'module-info.class',\n finns i roten av de angivna katalogerna eller det angivna jar-arkivet.\n F\u00F6ljande \u00E5tg\u00E4rder \u00E4r endast giltiga vid skapande av ett modul\u00E4rt jar-arkiv och\n vid uppdatering av ett befintligt icke-modul\u00E4rt jar-arkiv: '--module-version',\n '--hash-modules' och '--module-path'.\n\n Obligatoriska och valfria alternativ f\u00F6r l\u00E5nga alternativ \u00E4r \u00E4ven obligatoriska\n respektive valfria f\u00F6r alla motsvarande korta alternativ.
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=\u4E0D\u80FD\u6307\u5B9A\u591A\u4E2A '-cuxti' \u9009\u9879
+error.multiple.main.operations=\u4E0D\u80FD\u6307\u5B9A\u591A\u4E2A '-cuxtid' \u9009\u9879
 error.cant.open=\u65E0\u6CD5\u6253\u5F00: {0}
 error.illegal.option=\u975E\u6CD5\u9009\u9879: {0}
 error.unrecognized.option=\u65E0\u6CD5\u8BC6\u522B\u7684\u9009\u9879: {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=\u627E\u4E0D\u5230\u6A21\u5757\u63CF\u8FF0\u7B26
 error.versioned.info.without.root=\u5728\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u627E\u5230\u4E86 module-info.class, \u4F46\u6839\u4E2D\u6CA1\u6709 module-info.class
 error.versioned.info.name.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u6B63\u786E\u7684\u540D\u79F0
-error.versioned.info.requires.public=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 requires public
-error.versioned.info.requires.added=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 requires
-error.versioned.info.requires.dropped=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u7F3A\u5C11\u7684 requires
-error.versioned.info.exports.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 exports
-error.versioned.info.provides.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 provides
+error.versioned.info.requires.public=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 "requires public"
+error.versioned.info.requires.added=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 "requires"
+error.versioned.info.requires.dropped=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u7F3A\u5C11\u7684 "requires"
+error.versioned.info.exports.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "exports"
+error.versioned.info.provides.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "provides"
 error.invalid.versioned.module.attribute=\u65E0\u6548\u7684\u6A21\u5757\u63CF\u8FF0\u7B26\u5C5E\u6027 {0}
 error.missing.provider=\u672A\u627E\u5230\u670D\u52A1\u63D0\u4F9B\u65B9: {0}
 error.release.value.notnumber=\u53D1\u884C\u7248 {0} \u65E0\u6548
 error.release.value.toosmall=\u53D1\u884C\u7248 {0} \u65E0\u6548, \u5FC5\u987B >= 9
+error.validator.jarfile.exception=\u65E0\u6CD5\u9A8C\u8BC1 {0}: {1}
+error.validator.jarfile.invalid=\u5220\u9664\u7684\u591A\u53D1\u884C\u7248 jar \u6587\u4EF6 {0} \u65E0\u6548
+error.validator.bad.entry.name=\u6761\u76EE\u540D\u79F0\u683C\u5F0F\u9519\u8BEF, {0}
+error.validator.version.notnumber=\u6761\u76EE\u540D\u79F0 {0} \u6CA1\u6709\u7248\u672C\u53F7
+error.validator.entryname.tooshort=\u6761\u76EE\u540D\u79F0 {0} \u592A\u77ED, \u4E0D\u662F\u76EE\u5F55
+error.validator.isolated.nested.class=\u6761\u76EE {0} \u662F\u5355\u72EC\u7684\u5D4C\u5957\u7C7B
+error.validator.new.public.class=\u6761\u76EE {0} \u5305\u542B\u672A\u5728\u57FA\u7840\u6761\u76EE\u4E2D\u627E\u5230\u7684\u65B0\u516C\u5171\u7C7B
+error.validator.incompatible.class.version=\u6761\u76EE {0} \u5305\u542B\u4E0E\u8F83\u65E9\u7248\u672C\u4E0D\u517C\u5BB9\u7684\u7C7B\u7248\u672C
+error.validator.different.api=\u6761\u76EE {0} \u5305\u542B\u7684\u7C7B\u5177\u6709\u4E0E\u65E9\u671F\u7248\u672C\u4E0D\u540C\u7684 api
+error.validator.names.mismatch=\u6761\u76EE {0} \u5305\u542B\u5185\u90E8\u540D\u79F0\u4E3A {1} \u7684\u7C7B, \u540D\u79F0\u4E0D\u5339\u914D
+warn.validator.identical.entry=\u8B66\u544A - \u6761\u76EE {0} \u5305\u542B\u4E0E jar \u4E2D\u7684\u73B0\u6709\u6761\u76EE\u76F8\u540C\u7684\u7C7B
+warn.validator.resources.with.same.name=\u8B66\u544A - \u6761\u76EE {0}, \u591A\u4E2A\u8D44\u6E90\u540C\u540D
+warn.validator.concealed.public.class=\u8B66\u544A - \u6761\u76EE {0} \u662F\u9690\u85CF\u7A0B\u5E8F\u5305\u4E2D\u7684\u516C\u5171\u7C7B, \n\u5C06\u6B64 jar \u653E\u7F6E\u5728\u7C7B\u8DEF\u5F84\u4E2D\u5C06\u5BFC\u81F4\u516C\u5171\u63A5\u53E3\u4E0D\u517C\u5BB9
 out.added.manifest=\u5DF2\u6DFB\u52A0\u6E05\u5355
 out.added.module-info=\u5DF2\u6DFB\u52A0 module-info: {0}
 out.update.manifest=\u5DF2\u66F4\u65B0\u6E05\u5355
@@ -68,7 +81,7 @@
 
 usage.compat=\u517C\u5BB9\u6027\u63A5\u53E3:\n\u7528\u6CD5: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files] ...\n\u9009\u9879:\n    -c  \u521B\u5EFA\u65B0\u6863\u6848\n    -t  \u5217\u51FA\u6863\u6848\u76EE\u5F55\n    -x  \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6587\u4EF6\n    -u  \u66F4\u65B0\u73B0\u6709\u6863\u6848\n    -v  \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA\n    -f  \u6307\u5B9A\u6863\u6848\u6587\u4EF6\u540D\n    -m  \u5305\u542B\u6307\u5B9A\u6E05\u5355\u6587\u4EF6\u4E2D\u7684\u6E05\u5355\u4FE1\u606F\n    -n  \u521B\u5EFA\u65B0\u6863\u6848\u540E\u6267\u884C Pack200 \u89C4\u8303\u5316\n    -e  \u4E3A\u6346\u7ED1\u5230\u53EF\u6267\u884C jar \u6587\u4EF6\u7684\u72EC\u7ACB\u5E94\u7528\u7A0B\u5E8F\n        \u6307\u5B9A\u5E94\u7528\u7A0B\u5E8F\u5165\u53E3\u70B9\n    -0  \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528 ZIP \u538B\u7F29\n    -P  \u4FDD\u7559\u6587\u4EF6\u540D\u4E2D\u7684\u524D\u5BFC '/' (\u7EDD\u5BF9\u8DEF\u5F84) \u548C ".." (\u7236\u76EE\u5F55) \u7EC4\u4EF6\n    -M  \u4E0D\u521B\u5EFA\u6761\u76EE\u7684\u6E05\u5355\u6587\u4EF6\n    -i  \u4E3A\u6307\u5B9A\u7684 jar \u6587\u4EF6\u751F\u6210\u7D22\u5F15\u4FE1\u606F\n    -C  \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\u4EE5\u4E0B\u6587\u4EF6\n\u5982\u679C\u4EFB\u4F55\u6587\u4EF6\u4E3A\u76EE\u5F55, \u5219\u5BF9\u5176\u8FDB\u884C\u9012\u5F52\u5904\u7406\u3002\n\u6E05\u5355\u6587\u4EF6\u540D, \u6863\u6848\u6587\u4EF6\u540D\u548C\u5165\u53E3\u70B9\u540D\u79F0\u7684\u6307\u5B9A\u987A\u5E8F\n\u4E0E 'm', 'f' \u548C 'e' \u6807\u8BB0\u7684\u6307\u5B9A\u987A\u5E8F\u76F8\u540C\u3002\n\n\u793A\u4F8B 1: \u5C06\u4E24\u4E2A\u7C7B\u6587\u4EF6\u5F52\u6863\u5230\u4E00\u4E2A\u540D\u4E3A classes.jar \u7684\u6863\u6848\u4E2D: \n       jar cvf classes.jar Foo.class Bar.class \n\u793A\u4F8B 2: \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u6587\u4EF6 'mymanifest' \u5E76\n           \u5C06 foo/ \u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u5F52\u6863\u5230 'classes.jar' \u4E2D: \n       jar cvfm classes.jar mymanifest -C foo/ .\n
 
-main.usage.summary=jar: \u5FC5\u987B\u6307\u5B9A\u5176\u4E2D\u4E00\u4E2A -ctxui \u9009\u9879\u3002
+main.usage.summary=\u7528\u6CD5: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=\u5C1D\u8BD5\u4F7F\u7528 `jar --help' \u83B7\u53D6\u8BE6\u7EC6\u4FE1\u606F\u3002
 
 main.help.preopt=\u7528\u6CD5: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar \u521B\u5EFA\u7C7B\u548C\u8D44\u6E90\u7684\u6863\u6848, \u5E76\u4E14\u53EF\u4EE5\u5904\u7406\u6863\u6848\u4E2D\u7684\n\u5355\u4E2A\u7C7B\u6216\u8D44\u6E90\u6216\u8005\u4ECE\u6863\u6848\u4E2D\u8FD8\u539F\u5355\u4E2A\u7C7B\u6216\u8D44\u6E90\u3002\n\n \u793A\u4F8B:\n # \u521B\u5EFA\u5305\u542B\u4E24\u4E2A\u7C7B\u6587\u4EF6\u7684\u540D\u4E3A classes.jar \u7684\u6863\u6848:\n jar --create --file classes.jar Foo.class Bar.class\n # \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u521B\u5EFA\u6863\u6848, \u5176\u4E2D\u5305\u542B foo/ \u4E2D\u7684\u6240\u6709\u6587\u4EF6:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # \u521B\u5EFA\u6A21\u5757\u5316 jar \u6863\u6848, \u5176\u4E2D\u6A21\u5757\u63CF\u8FF0\u7B26\u4F4D\u4E8E\n # classes/module-info.class:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # \u5C06\u73B0\u6709\u7684\u975E\u6A21\u5757\u5316 jar \u66F4\u65B0\u4E3A\u6A21\u5757\u5316 jar:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # \u521B\u5EFA\u5305\u542B\u591A\u4E2A\u53D1\u884C\u7248\u7684 jar, \u5E76\u5C06\u4E00\u4E9B\u6587\u4EF6\u653E\u5728 META-INF/versions/9 \u76EE\u5F55\u4E2D:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 \u5217\u51FA\u6863\u6848\u7684\u76EE\u5F55
 main.help.opt.main.update=\  -u, --update               \u66F4\u65B0\u73B0\u6709 jar \u6863\u6848
 main.help.opt.main.extract=\  -x, --extract              \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u5168\u90E8) \u6587\u4EF6
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  \u8F93\u51FA\u6A21\u5757\u63CF\u8FF0\u7B26
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  \u8F93\u51FA\u6A21\u5757\u63CF\u8FF0\u7B26
 main.help.opt.any=\ \u5728\u4EFB\u610F\u6A21\u5F0F\u4E0B\u6709\u6548\u7684\u64CD\u4F5C\u4FEE\u9970\u7B26:\n\n  -C DIR                     \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\n                             \u4EE5\u4E0B\u6587\u4EF6
 main.help.opt.any.file=\  -f, --file=FILE            \u6863\u6848\u6587\u4EF6\u540D\n      --release VERSION      \u5C06\u4E0B\u9762\u7684\u6240\u6709\u6587\u4EF6\u90FD\u653E\u5728\n                             jar \u7684\u7248\u672C\u5316\u76EE\u5F55\u4E2D (\u5373 META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          \u4E0D\u4E3A\u6761\u76EE\u521B\u5EFA\u6E05\u5355\u6587\u4EF6
 main.help.opt.create.update.module-version=\      --module-version=VERSION    \u521B\u5EFA\u6A21\u5757\u5316 jar \u6216\u66F4\u65B0\n                             \u975E\u6A21\u5757\u5316 jar \u65F6\u7684\u6A21\u5757\u7248\u672C
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN \u8BA1\u7B97\u548C\u8BB0\u5F55\u6A21\u5757\u7684\u6563\u5217, \n                             \u8FD9\u4E9B\u6A21\u5757\u6309\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u5E76\u76F4\u63A5\u6216\n                             \u95F4\u63A5\u4F9D\u8D56\u4E8E\u6240\u521B\u5EFA\u7684\u6A21\u5757\u5316 jar \u6216\n                             \u6240\u66F4\u65B0\u7684\u975E\u6A21\u5757\u5316 jar
-main.help.opt.create.update.modulepath=\      --modulepath           \u6A21\u5757\u88AB\u4F9D\u8D56\u5BF9\u8C61\u7684\u4F4D\u7F6E, \u7528\u4E8E\u751F\u6210
-\                             \u6563\u5217
+main.help.opt.create.update.module-path=\  -p, --module-path          \u6A21\u5757\u88AB\u4F9D\u8D56\u5BF9\u8C61\u7684\u4F4D\u7F6E, \u7528\u4E8E\u751F\u6210\n                             \u6563\u5217
 main.help.opt.create.update.index=\ \u53EA\u5728\u521B\u5EFA, \u66F4\u65B0\u548C\u751F\u6210\u7D22\u5F15\u6A21\u5F0F\u4E0B\u6709\u6548\u7684\u64CD\u4F5C\u4FEE\u9970\u7B26:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528 ZIP \u538B\u7F29
 main.help.opt.other=\ \u5176\u4ED6\u9009\u9879:\n
 main.help.opt.other.help=\  -?, --help[:compat]        \u63D0\u4F9B\u6B64\u5E2E\u52A9, \u4E5F\u53EF\u4EE5\u9009\u62E9\u6027\u5730\u63D0\u4F9B\u517C\u5BB9\u6027\u5E2E\u52A9
 main.help.opt.other.version=\      --version              \u8F93\u51FA\u7A0B\u5E8F\u7248\u672C
-main.help.postopt=\ \u5982\u679C\u6A21\u5757\u63CF\u8FF0\u7B26 'module-info.class' \u4F4D\u4E8E\u6307\u5B9A\u76EE\u5F55\u7684\n \u6839\u76EE\u5F55\u4E2D, \u6216\u8005\u4F4D\u4E8E jar \u6863\u6848\u672C\u8EAB\u7684\u6839\u76EE\u5F55\u4E2D, \u5219\n \u8BE5\u6863\u6848\u662F\u4E00\u4E2A\u6A21\u5757\u5316 jar\u3002\u4EE5\u4E0B\u64CD\u4F5C\u53EA\u5728\u521B\u5EFA\u6A21\u5757\u5316 jar\n \u6216\u66F4\u65B0\u73B0\u6709\u7684\u975E\u6A21\u5757\u5316 jar \u65F6\u6709\u6548: '--module-version',\n --hash-modules' \u548C '--modulepath'\u3002\n\n \u5982\u679C\u4E3A\u957F\u9009\u9879\u63D0\u4F9B\u4E86\u5FC5\u9700\u53C2\u6570\u6216\u53EF\u9009\u53C2\u6570, \u5219\u5B83\u4EEC\u5BF9\u4E8E\n \u4EFB\u4F55\u5BF9\u5E94\u7684\u77ED\u9009\u9879\u4E5F\u662F\u5FC5\u9700\u6216\u53EF\u9009\u7684\u3002
+main.help.postopt=\ \u5982\u679C\u6A21\u5757\u63CF\u8FF0\u7B26 'module-info.class' \u4F4D\u4E8E\u6307\u5B9A\u76EE\u5F55\u7684\n \u6839\u76EE\u5F55\u4E2D, \u6216\u8005\u4F4D\u4E8E jar \u6863\u6848\u672C\u8EAB\u7684\u6839\u76EE\u5F55\u4E2D, \u5219\n \u8BE5\u6863\u6848\u662F\u4E00\u4E2A\u6A21\u5757\u5316 jar\u3002\u4EE5\u4E0B\u64CD\u4F5C\u53EA\u5728\u521B\u5EFA\u6A21\u5757\u5316 jar,\n \u6216\u66F4\u65B0\u73B0\u6709\u7684\u975E\u6A21\u5757\u5316 jar \u65F6\u6709\u6548: '--module-version',\n '--hash-modules' \u548C '--module-path'\u3002\n\n \u5982\u679C\u4E3A\u957F\u9009\u9879\u63D0\u4F9B\u4E86\u5FC5\u9700\u53C2\u6570\u6216\u53EF\u9009\u53C2\u6570, \u5219\u5B83\u4EEC\u5BF9\u4E8E\n \u4EFB\u4F55\u5BF9\u5E94\u7684\u77ED\u9009\u9879\u4E5F\u662F\u5FC5\u9700\u6216\u53EF\u9009\u7684\u3002
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_TW.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_TW.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 # questions.
 #
 
-error.multiple.main.operations=\u60A8\u4E0D\u80FD\u6307\u5B9A\u591A\u500B '-cuxti' \u9078\u9805
+error.multiple.main.operations=\u60A8\u4E0D\u80FD\u6307\u5B9A\u591A\u500B '-cuxtid' \u9078\u9805
 error.cant.open=\u7121\u6CD5\u958B\u555F: {0}
 error.illegal.option=\u7121\u6548\u7684\u9078\u9805: {0}
 error.unrecognized.option=\u7121\u6CD5\u8FA8\u8B58\u7684\u9078\u9805 : {0}
@@ -44,15 +44,28 @@
 error.module.descriptor.not.found=\u627E\u4E0D\u5230\u6A21\u7D44\u63CF\u8FF0\u5340
 error.versioned.info.without.root=\u5728\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u767C\u73FE module-info.class\uFF0C\u4F46\u662F\u6839\u4E2D\u6C92\u6709 module-info.class
 error.versioned.info.name.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u6B63\u78BA\u7684\u540D\u7A31
-error.versioned.info.requires.public=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684\u516C\u958B\u9700\u6C42\u9805\u76EE
-error.versioned.info.requires.added=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684\u9700\u6C42\u9805\u76EE
-error.versioned.info.requires.dropped=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u907A\u6F0F\u7684\u9700\u6C42\u9805\u76EE
-error.versioned.info.exports.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684\u532F\u51FA\u9805\u76EE
-error.versioned.info.provides.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684\u63D0\u4F9B\u9805\u76EE
+error.versioned.info.requires.public=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684 "requires public"
+error.versioned.info.requires.added=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684 "requires"
+error.versioned.info.requires.dropped=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u907A\u6F0F\u7684 "requires"
+error.versioned.info.exports.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "exports"
+error.versioned.info.provides.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "provides"
 error.invalid.versioned.module.attribute=\u6A21\u7D44\u63CF\u8FF0\u5340\u5C6C\u6027 {0} \u7121\u6548
 error.missing.provider=\u627E\u4E0D\u5230\u670D\u52D9\u63D0\u4F9B\u8005: {0}
 error.release.value.notnumber=\u7248\u672C {0} \u7121\u6548
 error.release.value.toosmall=\u7248\u672C {0} \u7121\u6548\uFF0C\u5FC5\u9808\u5927\u65BC\u7B49\u65BC 9
+error.validator.jarfile.exception=\u7121\u6CD5\u9A57\u8B49 {0}: {1}
+error.validator.jarfile.invalid=\u5DF2\u522A\u9664\u7121\u6548\u7684\u591A\u91CD\u7248\u672C jar \u6A94\u6848 {0}
+error.validator.bad.entry.name=\u9805\u76EE\u540D\u7A31 {0} \u7684\u683C\u5F0F\u932F\u8AA4
+error.validator.version.notnumber=\u9805\u76EE\u540D\u7A31 {0} \u6C92\u6709\u7248\u672C\u7DE8\u865F
+error.validator.entryname.tooshort=\u9805\u76EE\u540D\u7A31 {0} \u592A\u77ED\uFF0C\u7121\u6CD5\u4F5C\u70BA\u76EE\u9304
+error.validator.isolated.nested.class=\u9805\u76EE {0} \u662F\u5DF2\u9694\u96E2\u7684\u5DE2\u72C0\u7D50\u69CB\u985E\u5225
+error.validator.new.public.class=\u9805\u76EE {0} \u542B\u6709\u5728\u57FA\u6E96\u9805\u76EE\u4E2D\u627E\u4E0D\u5230\u7684\u65B0\u516C\u7528\u985E\u5225
+error.validator.incompatible.class.version=\u9805\u76EE {0} \u7684\u985E\u5225\u7248\u672C\u8207\u8F03\u820A\u7248\u672C\u4E0D\u76F8\u5BB9
+error.validator.different.api=\u9805\u76EE {0} \u7684\u67D0\u500B\u985E\u5225\u542B\u6709\u8207\u8F03\u820A\u7248\u672C\u4E0D\u540C\u7684 API
+error.validator.names.mismatch=\u9805\u76EE {0} \u542B\u6709\u5167\u90E8\u540D\u7A31\u70BA {1} \u7684\u985E\u5225\uFF0C\u540D\u7A31\u4E0D\u76F8\u7B26
+warn.validator.identical.entry=\u8B66\u544A - \u9805\u76EE {0} \u7684\u67D0\u500B\u985E\u5225\u8207 jar \u4E2D\u7684\u73FE\u6709\u9805\u76EE\u76F8\u540C
+warn.validator.resources.with.same.name=\u8B66\u544A - \u9805\u76EE {0} \u4E2D\u7684\u591A\u500B\u8CC7\u6E90\u540D\u7A31\u76F8\u540C
+warn.validator.concealed.public.class=\u8B66\u544A - \u9805\u76EE {0} \u662F\u96B1\u85CF\u5957\u88DD\u7A0B\u5F0F\u4E2D\u7684\u516C\u7528\u985E\u5225, \n\u5C07\u6B64 jar \u653E\u5728\u985E\u5225\u8DEF\u5F91\u4E0A\u6703\u9020\u6210\u516C\u7528\u4ECB\u9762\u4E0D\u76F8\u5BB9
 out.added.manifest=\u5DF2\u65B0\u589E\u8CC7\u8A0A\u6E05\u55AE
 out.added.module-info=\u5DF2\u65B0\u589E module-info: {0}
 out.update.manifest=\u5DF2\u66F4\u65B0\u8CC7\u8A0A\u6E05\u55AE
@@ -68,7 +81,7 @@
 
 usage.compat=\u76F8\u5BB9\u6027\u4ECB\u9762:\n\u7528\u6CD5: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files] ...\n\u9078\u9805:\n    -c  \u5EFA\u7ACB\u65B0\u5B58\u6A94\n    -t  \u5217\u51FA\u5B58\u6A94\u7684\u76EE\u9304\n    -x  \u5F9E\u5B58\u6A94\u4E2D\u64F7\u53D6\u6307\u5B9A (\u6216\u5168\u90E8) \u7684\u6A94\u6848\n    -u  \u66F4\u65B0\u73FE\u6709\u5B58\u6A94\n    -v  \u5728\u6A19\u6E96\u8F38\u51FA\u4E2D\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n    -f  \u6307\u5B9A\u5B58\u6A94\u6A94\u6848\u540D\u7A31\n    -m  \u5305\u542B\u6307\u5B9A\u4E4B\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n    -n  \u5728\u5EFA\u7ACB\u65B0\u5B58\u6A94\u4E4B\u5F8C\u57F7\u884C Pack200 \u6B63\u898F\u5316\n    -e  \u70BA\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\u7684\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F \n        \u6307\u5B9A\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE\n    -0  \u50C5\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n    -P  \u4FDD\u7559\u6A94\u6848\u540D\u7A31\u524D\u9762\u7684 '/' (\u7D55\u5C0D\u8DEF\u5F91) \u548C ".." (\u4E0A\u5C64\u76EE\u9304) \u5143\u4EF6\n    -M  \u4E0D\u70BA\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n    -i  \u70BA\u6307\u5B9A\u7684 jar \u6A94\u6848\u7522\u751F\u7D22\u5F15\u8CC7\u8A0A\n    -C  \u8B8A\u66F4\u81F3\u6307\u5B9A\u7684\u76EE\u9304\u4E26\u5305\u542B\u5F8C\u9762\u6240\u5217\u7684\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u5C0D\u5176\u9032\u884C\u905E\u8FF4\u8655\u7406\u3002\n\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u5B58\u6A94\u6A94\u6848\u540D\u7A31\u4EE5\u53CA\u9032\u5165\u9EDE\u540D\u7A31\n\u7684\u6307\u5B9A\u9806\u5E8F\u8207\u6307\u5B9A 'm'\u3001'f' \u4EE5\u53CA 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u5B58\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u5B58\u6A94\u4E2D: \n       jar cvf classes.jar Foo.class Bar.class \n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u7684\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest' \u4E26\u5C07\n           foo/ \u76EE\u9304\u4E2D\u7684\u6240\u6709\u6A94\u6848\u5B58\u6A94\u81F3 'classes.jar': \n       jar cvfm classes.jar mymanifest -C foo/\u3002\n
 
-main.usage.summary=jar: \u60A8\u5FC5\u9808\u6307\u5B9A\u5176\u4E2D\u4E00\u500B -ctxui \u9078\u9805\u3002
+main.usage.summary=\u7528\u6CD5: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
 main.usage.summary.try=\u8ACB\u4F7F\u7528 'jar --help' \u4EE5\u53D6\u5F97\u66F4\u591A\u7684\u8CC7\u8A0A\u3002
 
 main.help.preopt=\u7528\u6CD5: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...\njar \u6703\u5EFA\u7ACB\u985E\u5225\u548C\u8CC7\u6E90\u7684\u5B58\u6A94\uFF0C\u800C\u4E14\u53EF\u64CD\u63A7\u6216\n\u5F9E\u5B58\u6A94\u56DE\u5FA9\u500B\u5225\u985E\u5225\u6216\u8CC7\u6E90\u3002\n\n \u7BC4\u4F8B:\n # \u5EFA\u7ACB\u4E00\u500B\u540D\u70BA classes.jar \u4E14\u542B\u6709\u5169\u500B\u985E\u5225\u6A94\u6848\u7684\u5B58\u6A94:\n jar --create --file classes.jar Foo.class Bar.class\n # \u4F7F\u7528\u73FE\u6709\u7684\u8CC7\u8A0A\u6E05\u55AE\u548C foo/ \u4E2D\u7684\u6240\u6709\u6A94\u6848\u5EFA\u7ACB\u4E00\u500B\u5B58\u6A94:\n jar --create --file classes.jar --manifest mymanifest -C foo/ .\n # \u5EFA\u7ACB\u4E00\u500B\u6A21\u7D44\u5316 jar \u5B58\u6A94\uFF0C\u5176\u4E2D\u7684\u6A21\u7D44\u63CF\u8FF0\u5340\u4F4D\u65BC\n # classes/module-info.class:\n jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ classes resources\n # \u5C07\u73FE\u6709\u7684\u975E\u6A21\u7D44\u5316 jar \u66F4\u65B0\u70BA\u6A21\u7D44\u5316 jar:\n jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n     -C foo/ module-info.class\n # \u5EFA\u7ACB\u591A\u91CD\u7248\u672C\u7684 jar\uFF0C\u5C07\u90E8\u5206\u6A94\u6848\u653E\u7F6E\u5728 META-INF/versions/9 \u76EE\u9304\u4E2D:\n jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
@@ -78,7 +91,7 @@
 main.help.opt.main.list=\  -t, --list                 \u5217\u51FA\u5B58\u6A94\u7684\u76EE\u9304
 main.help.opt.main.update=\  -u, --update               \u66F4\u65B0\u73FE\u6709\u7684 jar \u5B58\u6A94
 main.help.opt.main.extract=\  -x, --extract              \u5F9E\u5B58\u6A94\u4E2D\u64F7\u53D6\u6307\u5B9A (\u6216\u6240\u6709) \u6A94\u6848
-main.help.opt.main.print-module-descriptor=\  -p, --print-module-descriptor  \u5217\u5370\u6A21\u7D44\u63CF\u8FF0\u5340
+main.help.opt.main.print-module-descriptor=\  -d, --print-module-descriptor  \u5217\u5370\u6A21\u7D44\u63CF\u8FF0\u5340
 main.help.opt.any=\ \u53EF\u5728\u4EFB\u4F55\u6A21\u5F0F\u4E0B\u4F7F\u7528\u7684\u4F5C\u696D\u4FEE\u98FE\u689D\u4EF6:\n\n  -C DIR                     \u8B8A\u66F4\u70BA\u6307\u5B9A\u76EE\u9304\u4E26\u5305\u542B\n                             \u4E0B\u5217\u6A94\u6848
 main.help.opt.any.file=\  -f, --file=FILE            \u5B58\u6A94\u6A94\u6848\u540D\u7A31\n      --release VERSION      \u5C07\u6240\u6709\u4E0B\u5217\u6A94\u6848\u653E\u7F6E\u5728 jar \u7684\u5DF2\u555F\u52D5\u591A\u7248\u672C\n                             \u529F\u80FD\u76EE\u9304\u4E2D (\u4F8B\u5982 META-INF/versions/VERSION/)
 main.help.opt.any.verbose=\  -v, --verbose              \u5728\u6A19\u6E96\u8F38\u51FA\u4E2D\u7522\u751F\u8A73\u7D30\u8F38\u51FA
@@ -88,11 +101,10 @@
 main.help.opt.create.update.no-manifest=\  -M, --no-manifest          \u4E0D\u70BA\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848
 main.help.opt.create.update.module-version=\      --module-version=VERSION    \u5EFA\u7ACB\u6A21\u7D44\u5316 jar \u6216\u66F4\u65B0\u975E\u6A21\u7D44\u5316 jar \u6642\n                             \u4F7F\u7528\u7684\u6A21\u7D44\u7248\u672C
 main.help.opt.create.update.hash-modules=\      --hash-modules=PATTERN \u904B\u7B97\u53CA\u8A18\u9304\u8207\u6307\u5B9A\u6A23\u5F0F\n                             \u76F8\u7B26\u7684\u6A21\u7D44\u96DC\u6E4A\uFF0C\u9019\u76F4\u63A5\u6216\u9593\u63A5\u5730\n                             \u76F8\u4F9D\u65BC\u6B63\u5728\u5EFA\u7ACB\u7684\u6A21\u7D44\u5316 jar \u6216\u6B63\u5728\n                             \u66F4\u65B0\u7684\u975E\u6A21\u7D44\u5316 jar
-main.help.opt.create.update.modulepath=\      --modulepath           \u6A21\u7D44\u76F8\u4F9D\u6027\u7684\u4F4D\u7F6E\uFF0C\u7528\u65BC\u7522\u751F
-\                             \u96DC\u6E4A
+main.help.opt.create.update.module-path=\  -p, --module-path          \u6A21\u7D44\u76F8\u4F9D\u6027\u7684\u4F4D\u7F6E\uFF0C\u7528\u65BC\u7522\u751F\n                             \u96DC\u6E4A
 main.help.opt.create.update.index=\ \u53EA\u80FD\u5728\u5EFA\u7ACB\u3001\u66F4\u65B0\u53CA\u7522\u751F\u7D22\u5F15\u6A21\u5F0F\u4E0B\u4F7F\u7528\u7684\u4F5C\u696D\u4FEE\u98FE\u689D\u4EF6:\n
 main.help.opt.create.update.index.no-compress=\  -0, --no-compress          \u50C5\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F
 main.help.opt.other=\ \u5176\u4ED6\u9078\u9805:\n
 main.help.opt.other.help=\  -?, --help[:compat]        \u63D0\u4F9B\u6B64\u8AAA\u660E\u6216\u9078\u64C7\u6027\u986F\u793A\u76F8\u5BB9\u6027\u8AAA\u660E
 main.help.opt.other.version=\      --version              \u5217\u5370\u7A0B\u5F0F\u7248\u672C
-main.help.postopt=\ \u5982\u679C\u6A21\u7D44\u63CF\u8FF0\u5340 ('module-info.class') \u4F4D\u65BC\u6307\u5B9A\u76EE\u9304\u7684\u6839\n \u6216 jar \u5B58\u6A94\u672C\u8EAB\u7684\u6839\uFF0C\u5247\u5B58\u6A94\u6703\u662F\n \u6A21\u7D44\u5316\u7684 jar\u3002\u4E0B\u5217\u4F5C\u696D\u53EA\u80FD\u5728\u5EFA\u7ACB\u6A21\u7D44\u5316 jar \u6216\u66F4\u65B0\n \u73FE\u6709\u975E\u6A21\u7D44\u5316 jar \u6642\u9032\u884C: '--module-version'\u3001\n '--hash-modules' \u548C '--modulepath'\u3002\n\n \u9577\u9078\u9805\u7684\u5F37\u5236\u6027\u6216\u9078\u64C7\u6027\u5F15\u6578\u4E5F\u6703\u662F\u4EFB\u4F55\u5C0D\u61C9\u77ED\u9078\u9805\u7684\n \u5F37\u5236\u6027\u6216\u9078\u64C7\u6027\u5F15\u6578\u3002
+main.help.postopt=\ \u5982\u679C\u6A21\u7D44\u63CF\u8FF0\u5340 ('module-info.class') \u4F4D\u65BC\u6307\u5B9A\u76EE\u9304\u7684\u6839\n \u6216 jar \u5B58\u6A94\u672C\u8EAB\u7684\u6839\uFF0C\u5247\u5B58\u6A94\u6703\u662F\n \u6A21\u7D44\u5316\u7684 jar\u3002\u4E0B\u5217\u4F5C\u696D\u53EA\u80FD\u5728\u5EFA\u7ACB\u6A21\u7D44\u5316 jar \u6216\u66F4\u65B0\n \u73FE\u6709\u975E\u6A21\u7D44\u5316 jar \u6642\u9032\u884C: '--module-version'\u3001\n '--hash-modules' \u548C '--module-path'\u3002\n\n \u9577\u9078\u9805\u7684\u5F37\u5236\u6027\u6216\u9078\u64C7\u6027\u5F15\u6578\u4E5F\u6703\u662F\u4EFB\u4F55\u5C0D\u61C9\u77ED\u9078\u9805\u7684\n \u5F37\u5236\u6027\u6216\u9078\u64C7\u6027\u5F15\u6578\u3002
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Tue Dec 13 02:04:23 2016 +0100
@@ -141,37 +141,41 @@
         Files.createDirectories(mdir);
     }
 
-    private void storeFiles(Set<String> modules, Properties release) throws IOException {
-        if (release != null) {
-            addModules(release, modules);
-            File r = new File(root.toFile(), "release");
-            try (FileOutputStream fo = new FileOutputStream(r)) {
-                release.store(fo, null);
+    private void storeRelease(ResourcePool pool) throws IOException {
+        Properties props = new Properties();
+        Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
+        if (release.isPresent()) {
+            try (InputStream is = release.get().content()) {
+                props.load(is);
             }
         }
-    }
-
-    private void addModules(Properties props, Set<String> modules) throws IOException {
-        StringBuilder builder = new StringBuilder();
-        int i = 0;
-        for (String m : modules) {
-            builder.append(m);
-            if (i < modules.size() - 1) {
-                builder.append(",");
-            }
-            i++;
+        File r = new File(root.toFile(), "release");
+        try (FileOutputStream fo = new FileOutputStream(r)) {
+            props.store(fo, null);
         }
-        props.setProperty("MODULES", quote(builder.toString()));
     }
 
     @Override
     public void storeFiles(ResourcePool files) {
         try {
-            // populate release properties up-front. targetOsName
-            // field is assigned from there and used elsewhere.
-            Properties release = releaseProperties(files);
+            // populate targetOsName field up-front because it's used elsewhere.
+            Optional<ResourcePoolModule> javaBase = files.moduleView().findModule("java.base");
+            javaBase.ifPresent(mod -> {
+                // fill release information available from transformed "java.base" module!
+                ModuleDescriptor desc = mod.descriptor();
+                desc.osName().ifPresent(s -> {
+                    this.targetOsName = s;
+                });
+            });
+
+            if (this.targetOsName == null) {
+                throw new PluginException("TargetPlatform attribute is missing for java.base module");
+            }
+
+            // store 'release' file
+            storeRelease(files);
+
             Path bin = root.resolve("bin");
-
             // check any duplicated resource files
             Map<Path, Set<String>> duplicates = new HashMap<>();
             files.entries()
@@ -209,8 +213,6 @@
                 }
             });
 
-            storeFiles(modules, release);
-
             if (root.getFileSystem().supportedFileAttributeViews()
                     .contains("posix")) {
                 // launchers in the bin directory need execute permission.
@@ -241,52 +243,6 @@
         }
     }
 
-    // Parse version string and return a string that includes only version part
-    // leaving "pre", "build" information. See also: java.lang.Runtime.Version.
-    private static String parseVersion(String str) {
-        return Runtime.Version.parse(str).
-            version().
-            stream().
-            map(Object::toString).
-            collect(joining("."));
-    }
-
-    private static String quote(String str) {
-        return "\"" + str + "\"";
-    }
-
-    private Properties releaseProperties(ResourcePool pool) throws IOException {
-        Properties props = new Properties();
-        Optional<ResourcePoolModule> javaBase = pool.moduleView().findModule("java.base");
-        javaBase.ifPresent(mod -> {
-            // fill release information available from transformed "java.base" module!
-            ModuleDescriptor desc = mod.descriptor();
-            desc.osName().ifPresent(s -> {
-                props.setProperty("OS_NAME", quote(s));
-                this.targetOsName = s;
-            });
-            desc.osVersion().ifPresent(s -> props.setProperty("OS_VERSION", quote(s)));
-            desc.osArch().ifPresent(s -> props.setProperty("OS_ARCH", quote(s)));
-            desc.version().ifPresent(s -> props.setProperty("JAVA_VERSION",
-                    quote(parseVersion(s.toString()))));
-            desc.version().ifPresent(s -> props.setProperty("JAVA_FULL_VERSION",
-                    quote(s.toString())));
-        });
-
-        if (this.targetOsName == null) {
-            throw new PluginException("TargetPlatform attribute is missing for java.base module");
-        }
-
-        Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
-        if (release.isPresent()) {
-            try (InputStream is = release.get().content()) {
-                props.load(is);
-            }
-        }
-
-        return props;
-    }
-
     /**
      * Generates launcher scripts.
      *
@@ -561,7 +517,7 @@
             }
             String mods = release.getProperty("MODULES");
             if (mods != null) {
-                String[] arr = mods.split(",");
+                String[] arr = mods.substring(1, mods.length() - 1).split(" ");
                 for (String m : arr) {
                     modules.add(m.trim());
                 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java	Tue Dec 13 02:04:23 2016 +0100
@@ -43,6 +43,9 @@
  */
 public final class ImagePluginConfiguration {
 
+    // Order in which plugins are applied. Note that COMPRESSOR type plugins should come
+    // after any plugin that reads .class resources and operate on binary data.
+    // Plugin.Category enum element order matches this order for ease of read.
     private static final List<Category> CATEGORIES_ORDER = new ArrayList<>();
 
     static {
@@ -50,8 +53,8 @@
         CATEGORIES_ORDER.add(Category.TRANSFORMER);
         CATEGORIES_ORDER.add(Category.MODULEINFO_TRANSFORMER);
         CATEGORIES_ORDER.add(Category.SORTER);
+        CATEGORIES_ORDER.add(Category.METAINFO_ADDER);
         CATEGORIES_ORDER.add(Category.COMPRESSOR);
-        CATEGORIES_ORDER.add(Category.METAINFO_ADDER);
         CATEGORIES_ORDER.add(Category.VERIFIER);
         CATEGORIES_ORDER.add(Category.PROCESSOR);
         CATEGORIES_ORDER.add(Category.PACKAGER);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleSorter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
+import jdk.tools.jlink.plugin.ResourcePoolModuleView;
+
+import java.lang.module.ModuleDescriptor;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
+
+/**
+ * Helper class to sort modules in topological order
+ */
+public final class ModuleSorter {
+    private final Deque<ResourcePoolModule> nodes = new LinkedList<>();
+    private final Map<String, Set<ResourcePoolModule>> edges = new HashMap<>();
+    private final Deque<ResourcePoolModule> result = new LinkedList<>();
+
+    private final ResourcePoolModuleView moduleView;
+
+    public ModuleSorter(ResourcePoolModuleView moduleView) {
+        this.moduleView = moduleView;
+
+        moduleView.modules().forEach(this::addModule);
+    }
+
+    private ModuleSorter addModule(ResourcePoolModule module) {
+        ModuleDescriptor descriptor = module.descriptor();
+        addNode(module);
+        descriptor.requires().stream()
+            .forEach(req -> {
+                String dm = req.name();
+                ResourcePoolModule dep = moduleView.findModule(dm)
+                    .orElseThrow(() -> new PluginException(dm + " not found"));
+                addNode(dep);
+                edges.get(module.name()).add(dep);
+            });
+        return this;
+    }
+
+    private void addNode(ResourcePoolModule module) {
+        nodes.add(module);
+        edges.computeIfAbsent(module.name(), _n -> new HashSet<>());
+    }
+
+    private synchronized void build() {
+        if (!result.isEmpty() || nodes.isEmpty())
+            return;
+
+        Deque<ResourcePoolModule> visited = new LinkedList<>();
+        Deque<ResourcePoolModule> done = new LinkedList<>();
+        ResourcePoolModule node;
+        while ((node = nodes.poll()) != null) {
+            if (!visited.contains(node)) {
+                visit(node, visited, done);
+            }
+        }
+    }
+
+    public Stream<ResourcePoolModule> sorted() {
+        build();
+        return result.stream();
+    }
+
+    private void visit(ResourcePoolModule node,
+                       Deque<ResourcePoolModule> visited,
+                       Deque<ResourcePoolModule> done) {
+        if (visited.contains(node)) {
+            if (!done.contains(node)) {
+                throw new IllegalArgumentException("Cyclic detected: " +
+                    node + " " + edges.get(node.name()));
+            }
+            return;
+        }
+        visited.add(node);
+        edges.get(node.name()).stream()
+             .forEach(x -> visit(x, visited, done));
+        done.add(node);
+        result.addLast(node);
+    }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Tue Dec 13 02:04:23 2016 +0100
@@ -56,7 +56,11 @@
                       + " module");
         }
         ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
-        return ModuleDescriptor.read(bb);
+        try {
+            return ModuleDescriptor.read(bb);
+        } catch (RuntimeException re) {
+            throw new RuntimeException("module descriptor cannot be read for " + mod.name(), re);
+        }
     }
 
     /**
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Tue Dec 13 02:04:23 2016 +0100
@@ -36,6 +36,8 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Collectors;
+import jdk.tools.jlink.internal.ModuleSorter;
 import jdk.tools.jlink.internal.Utils;
 import jdk.tools.jlink.plugin.ResourcePool;
 import jdk.tools.jlink.plugin.ResourcePoolBuilder;
@@ -71,7 +73,7 @@
 
     @Override
     public Set<State> getState() {
-        return EnumSet.of(State.FUNCTIONAL);
+        return EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL);
     }
 
     @Override
@@ -87,6 +89,10 @@
     @Override
     public void configure(Map<String, String> config) {
         String operation = config.get(NAME);
+        if (operation == null) {
+            return;
+        }
+
         switch (operation) {
             case "add": {
                 // leave it to open-ended! source, java_version, java_full_version
@@ -127,12 +133,46 @@
     public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy(Function.identity(), out);
 
+        Optional<ResourcePoolModule> javaBase = in.moduleView().findModule("java.base");
+        javaBase.ifPresent(mod -> {
+            // fill release information available from transformed "java.base" module!
+            ModuleDescriptor desc = mod.descriptor();
+            desc.osName().ifPresent(s -> {
+                release.put("OS_NAME", quote(s));
+            });
+            desc.osVersion().ifPresent(s -> release.put("OS_VERSION", quote(s)));
+            desc.osArch().ifPresent(s -> release.put("OS_ARCH", quote(s)));
+            desc.version().ifPresent(s -> release.put("JAVA_VERSION",
+                    quote(parseVersion(s.toString()))));
+            desc.version().ifPresent(s -> release.put("JAVA_FULL_VERSION",
+                    quote(s.toString())));
+        });
+
+        // put topological sorted module names separated by space
+        release.put("MODULES",  new ModuleSorter(in.moduleView())
+                .sorted().map(ResourcePoolModule::name)
+                .collect(Collectors.joining(" ", "\"", "\"")));
+
         // create a TOP level ResourcePoolEntry for "release" file.
         out.add(ResourcePoolEntry.create("/java.base/release",
             ResourcePoolEntry.Type.TOP, releaseFileContent()));
         return out.build();
     }
 
+    // Parse version string and return a string that includes only version part
+    // leaving "pre", "build" information. See also: java.lang.Runtime.Version.
+    private static String parseVersion(String str) {
+        return Runtime.Version.parse(str).
+            version().
+            stream().
+            map(Object::toString).
+            collect(Collectors.joining("."));
+    }
+
+    private static String quote(String str) {
+        return "\"" + str + "\"";
+    }
+
     private byte[] releaseFileContent() {
         Properties props = new Properties();
         props.putAll(release);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java	Tue Dec 13 02:04:23 2016 +0100
@@ -36,15 +36,15 @@
 public interface Plugin {
 
     /**
-     * Order of categories:
+     * Order of categories matches the plugin sort order.
      * <ol>
      * <li>FILTER: Filter in/out resources or files.</li>
      * <li>TRANSFORMER: Transform resources or files(eg: refactoring, bytecode
      * manipulation).</li>
      * <li>MODULEINFO_TRANSFORMER: Transform only module-info.class</li>
      * <li>SORTER: Sort resources within the resource container.</li>
+     * <li>METAINFO_ADDER: Added meta info (like release, copyright etc.)</li>
      * <li>COMPRESSOR: Compress resource within the resouce containers.</li>
-     * <li>METAINFO_ADDER: Added meta info (like release, copyright etc.)</li>
      * <li>VERIFIER: Does some image verification.</li>
      * <li>PROCESSOR: Does some post processing on image.</li>
      * <li>PACKAGER: Final processing</li>
@@ -55,8 +55,8 @@
         TRANSFORMER("TRANSFORMER"),
         MODULEINFO_TRANSFORMER("MODULEINFO_TRANSFORMER"),
         SORTER("SORTER"),
+        METAINFO_ADDER("METAINFO_ADDER"),
         COMPRESSOR("COMPRESSOR"),
-        METAINFO_ADDER("METAINFO_ADDER"),
         VERIFIER("VERIFIER"),
         PROCESSOR("PROCESSOR"),
         PACKAGER("PACKAGER");
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,22 +23,22 @@
 # questions.
 #
 
-main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> --modulepath <modulepath> --addmods <mods> --output <path>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001--help\u3092\u4F7F\u7528\u3057\u307E\u3059
+main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> --module-path <modulepath> --add-modules <mods> --output <path>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001--help\u3092\u4F7F\u7528\u3057\u307E\u3059
 
-main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> --modulepath <modulepath> --addmods <mods> --output <path>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002
+main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> --module-path <modulepath> --add-modules <mods> --output <path>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059:
 
 error.prefix=\u30A8\u30E9\u30FC:
 warn.prefix=\u8B66\u544A:
 
-main.opt.help=\  --help                            \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3057\u307E\u3059
+main.opt.help=\  -h\u3001--help                        \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3057\u307E\u3059
 
 main.opt.version=\  --version                         \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
 
-main.opt.modulepath=\  --modulepath <modulepath>         \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9
+main.opt.module-path=\  -p <modulepath>\n  --module-path <modulepath>        \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9
 
-main.opt.addmods=\  --addmods <mod>[,<mod>...]        \u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB
+main.opt.add-modules=\  --add-modules <mod>[,<mod>...]    \u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB
 
-main.opt.limitmods=\  --limitmods <mod>[,<mod>...]      \u76E3\u8996\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30E6\u30CB\u30D0\u30FC\u30B9\u3092\u5236\u9650\u3057\u307E\u3059
+main.opt.limit-modules=\  --limit-modules <mod>[,<mod>...]  \u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3057\u307E\u3059
 
 main.opt.output=\  --output <path>                   \u51FA\u529B\u30D1\u30B9\u306E\u5834\u6240
 
@@ -46,7 +46,7 @@
 
 main.opt.endian=\  --endian <little|big>             \u751F\u6210\u3055\u308C\u305Fjimage (default:native)\u306E\u30D0\u30A4\u30C8\u9806
 
-main.opt.saveopts=\  --saveopts <filename>             \u6307\u5B9A\u306E\u30D5\u30A1\u30A4\u30EB\u306Bjlink\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4FDD\u5B58\u3057\u307E\u3059
+main.opt.save-opts=\  --save-opts <filename>            \u6307\u5B9A\u306E\u30D5\u30A1\u30A4\u30EB\u306Bjlink\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4FDD\u5B58\u3057\u307E\u3059
 
 main.msg.bug=jlink\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java Bug Database (http://bugreport.java.com/bugreport/)\u3067bug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002
 
@@ -56,7 +56,7 @@
 
 err.unknown.byte.order:\u4E0D\u660E\u306A\u30D0\u30A4\u30C8\u9806{0}
 err.output.must.be.specified:--output\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
-err.modulepath.must.be.specified:--modulepath\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
+err.modulepath.must.be.specified:--module-path\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
 err.mods.must.be.specified:{0}\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 err.path.not.found=\u30D1\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}
 err.path.not.valid=\u7121\u52B9\u306A\u30D1\u30B9: {0}
@@ -67,6 +67,7 @@
 err.dir.exists={0}\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059
 err.badpattern=\u4E0D\u6B63\u30D1\u30BF\u30FC\u30F3{0}
 err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
+err.orphan.argument=\u5B64\u7ACB\u3057\u305F\u5F15\u6570: {0}
 err.missing.arg={0}\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 err.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC: {0} {1} {2}
 err.invalid.arg.for.option=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -23,22 +23,22 @@
 # questions.
 #
 
-main.usage.summary=\u7528\u6CD5: {0} <options> --modulepath <modulepath> --addmods <mods> --output <path>\n\u4F7F\u7528 --help \u53EF\u4EE5\u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
+main.usage.summary=\u7528\u6CD5: {0} <\u9009\u9879> --module-path <\u6A21\u5757\u8DEF\u5F84> --add-modules <\u6A21\u5757> --output <\u8DEF\u5F84>\n\u4F7F\u7528 --help \u53EF\u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
 
-main.usage=\u7528\u6CD5: {0} <options> --modulepath <modulepath> --addmods <mods> --output <path>\n\u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
+main.usage=\u7528\u6CD5: {0} <\u9009\u9879> --module-path <\u6A21\u5757\u8DEF\u5F84> --add-modules <\u6A21\u5757> --output <\u8DEF\u5F84>\n\u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
 
 error.prefix=\u9519\u8BEF:
 warn.prefix=\u8B66\u544A:
 
-main.opt.help=\  --help                            \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F
+main.opt.help=\  -h, --help                        \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F
 
 main.opt.version=\  --version                         \u7248\u672C\u4FE1\u606F
 
-main.opt.modulepath=\  --modulepath <modulepath>         \u6A21\u5757\u8DEF\u5F84
+main.opt.module-path=\  -p <\u6A21\u5757\u8DEF\u5F84>\n  --module-path <\u6A21\u5757\u8DEF\u5F84>        \u6A21\u5757\u8DEF\u5F84
 
-main.opt.addmods=\  --addmods <mod>[,<mod>...]        \u8981\u89E3\u6790\u7684\u6839\u6A21\u5757
+main.opt.add-modules=\  --add-modules <\u6A21\u5757>[,<\u6A21\u5757>...]    \u8981\u89E3\u6790\u7684\u6839\u6A21\u5757
 
-main.opt.limitmods=\  --limitmods <mod>[,<mod>...]      \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF
+main.opt.limit-modules=\  --limit-modules <\u6A21\u5757>[,<\u6A21\u5757>...]  \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF
 
 main.opt.output=\  --output <path>                   \u8F93\u51FA\u8DEF\u5F84\u7684\u4F4D\u7F6E
 
@@ -46,7 +46,7 @@
 
 main.opt.endian=\  --endian <little|big>             \u6240\u751F\u6210 jimage \u7684\u5B57\u8282\u987A\u5E8F (\u9ED8\u8BA4\u503C: native)
 
-main.opt.saveopts=\  --saveopts <filename>             \u5C06 jlink \u9009\u9879\u4FDD\u5B58\u5728\u6307\u5B9A\u6587\u4EF6\u4E2D
+main.opt.save-opts=\  --save-opts <\u6587\u4EF6\u540D>            \u5C06 jlink \u9009\u9879\u4FDD\u5B58\u5728\u6307\u5B9A\u6587\u4EF6\u4E2D
 
 main.msg.bug=jlink \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Java Bug Database (http://bugreport.java.com/bugreport/) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF, \u8BF7\u5728\u8BE5\u6570\u636E\u5E93\u4E2D\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002
 
@@ -56,7 +56,7 @@
 
 err.unknown.byte.order:\u672A\u77E5\u7684\u5B57\u8282\u987A\u5E8F {0}
 err.output.must.be.specified:\u5FC5\u987B\u6307\u5B9A --output
-err.modulepath.must.be.specified:\u5FC5\u987B\u6307\u5B9A --modulepath
+err.modulepath.must.be.specified:\u5FC5\u987B\u6307\u5B9A --module-path
 err.mods.must.be.specified:\u6CA1\u6709\u5C06\u4EFB\u4F55\u6A21\u5757\u6307\u5B9A\u5230{0}
 err.path.not.found=\u627E\u4E0D\u5230\u8DEF\u5F84: {0}
 err.path.not.valid=\u65E0\u6548\u8DEF\u5F84: {0}
@@ -67,6 +67,7 @@
 err.dir.exists={0} \u5DF2\u5B58\u5728
 err.badpattern=\u9519\u8BEF\u7684\u6A21\u5F0F {0}
 err.unknown.option=\u672A\u77E5\u9009\u9879: {0}
+err.orphan.argument=\u5B64\u7ACB\u7684\u53C2\u6570: {0}
 err.missing.arg=\u6CA1\u6709\u4E3A{0}\u6307\u5B9A\u503C
 err.internal.error=\u5185\u90E8\u9519\u8BEF: {0} {1} {2}
 err.invalid.arg.for.option=\u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java	Tue Dec 13 02:04:23 2016 +0100
@@ -36,6 +36,7 @@
 import java.nio.file.Paths;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
+import jdk.internal.jmod.JmodFile;
 
 import static jdk.internal.jmod.JmodFile.*;
 
@@ -57,7 +58,7 @@
     private JmodOutputStream(OutputStream out) {
         this.zos = new ZipOutputStream(out);
         try {
-            out.write(JMOD_MAGIC_NUMBER);
+            JmodFile.writeMagicNumber(out);
         } catch (IOException e) {
             throw new UncheckedIOException(e);
         }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Tue Dec 13 02:04:23 2016 +0100
@@ -138,6 +138,8 @@
     private static final String PROGNAME = "jmod";
     private static final String MODULE_INFO = "module-info.class";
 
+    private static final Path CWD = Paths.get("");
+
     private Options options;
     private PrintWriter out = new PrintWriter(System.out, true);
     void setLog(PrintWriter out, PrintWriter err) {
@@ -153,6 +155,7 @@
 
     enum Mode {
         CREATE,
+        EXTRACT,
         LIST,
         DESCRIBE,
         HASH
@@ -178,6 +181,7 @@
         Pattern modulesToHash;
         boolean dryrun;
         List<PathMatcher> excludes;
+        Path extractDir;
     }
 
     public int run(String[] args) {
@@ -202,6 +206,9 @@
                 case CREATE:
                     ok = create();
                     break;
+                case EXTRACT:
+                    ok = extract();
+                    break;
                 case LIST:
                     ok = list();
                     break;
@@ -248,6 +255,32 @@
         }
     }
 
+    private boolean extract() throws IOException {
+        Path dir = options.extractDir != null ? options.extractDir : CWD;
+        try (JmodFile jf = new JmodFile(options.jmodFile)) {
+            jf.stream().forEach(e -> {
+                try {
+                    ZipEntry entry = e.zipEntry();
+                    String name = entry.getName();
+                    int index = name.lastIndexOf("/");
+                    if (index != -1) {
+                        Path p = dir.resolve(name.substring(0, index));
+                        if (Files.notExists(p))
+                            Files.createDirectories(p);
+                    }
+
+                    try (OutputStream os = Files.newOutputStream(dir.resolve(name))) {
+                        jf.getInputStream(e).transferTo(os);
+                    }
+                } catch (IOException x) {
+                    throw new UncheckedIOException(x);
+                }
+            });
+
+            return true;
+        }
+    }
+
     private boolean hashModules() {
         return new Hasher(options.moduleFinder).run();
     }
@@ -1019,8 +1052,6 @@
     static class ClassPathConverter implements ValueConverter<Path> {
         static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
 
-        private static final Path CWD = Paths.get("");
-
         @Override
         public Path convert(String value) {
             try {
@@ -1044,8 +1075,6 @@
     static class DirPathConverter implements ValueConverter<Path> {
         static final ValueConverter<Path> INSTANCE = new DirPathConverter();
 
-        private static final Path CWD = Paths.get("");
-
         @Override
         public Path convert(String value) {
             try {
@@ -1065,6 +1094,33 @@
         @Override  public String valuePattern() { return "path"; }
     }
 
+    static class ExtractDirPathConverter implements ValueConverter<Path> {
+
+        @Override
+        public Path convert(String value) {
+            try {
+                Path path = CWD.resolve(value);
+                if (Files.exists(path)) {
+                    if (!Files.isDirectory(path))
+                        throw new CommandException("err.cannot.create.dir", path);
+                } else {
+                    try {
+                        Files.createDirectories(path);
+                    } catch (IOException ioe) {
+                        throw new CommandException("err.cannot.create.dir", path);
+                    }
+                }
+                return path;
+            } catch (InvalidPathException x) {
+                throw new CommandException("err.path.not.valid", value);
+            }
+        }
+
+        @Override  public Class<Path> valueType() { return Path.class; }
+
+        @Override  public String valuePattern() { return "path"; }
+    }
+
     static class ModuleVersionConverter implements ValueConverter<Version> {
         @Override
         public Version convert(String value) {
@@ -1158,6 +1214,7 @@
 
             builder.append(getMessage("main.opt.mode")).append("\n  ");
             builder.append(getMessage("main.opt.mode.create")).append("\n  ");
+            builder.append(getMessage("main.opt.mode.extract")).append("\n  ");
             builder.append(getMessage("main.opt.mode.list")).append("\n  ");
             builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
             builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
@@ -1203,6 +1260,11 @@
                         .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
+        OptionSpec<Path> dir
+                = parser.accepts("dir", getMessage("main.opt.extractDir"))
+                        .withRequiredArg()
+                        .withValuesConvertedBy(new ExtractDirPathConverter());
+
         OptionSpec<Void> dryrun
             = parser.accepts("dry-run", getMessage("main.opt.dry-run"));
 
@@ -1303,6 +1365,8 @@
                 options.cmds = opts.valuesOf(cmds);
             if (opts.has(config))
                 options.configs = opts.valuesOf(config);
+            if (opts.has(dir))
+                options.extractDir = opts.valueOf(dir);
             if (opts.has(dryrun))
                 options.dryrun = true;
             if (opts.has(excludes))
@@ -1347,7 +1411,8 @@
                 if (options.mode.equals(Mode.CREATE) && Files.exists(path))
                     throw new CommandException("err.file.already.exists", path);
                 else if ((options.mode.equals(Mode.LIST) ||
-                            options.mode.equals(Mode.DESCRIBE))
+                            options.mode.equals(Mode.DESCRIBE) ||
+                            options.mode.equals((Mode.EXTRACT)))
                          && Files.notExists(path))
                     throw new CommandException("err.jmod.not.found", path);
 
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,11 +24,11 @@
 #
 
 main.usage.summary=\
-Usage: {0} (create|list|describe|hash) <OPTIONS> <jmod-file>\n\
+Usage: {0} (create|extract|list|describe|hash) <OPTIONS> <jmod-file>\n\
 use --help for a list of possible options
 
 main.usage=\
-Usage: {0} (create|list|describe|hash) <OPTIONS> <jmod-file>\n\
+Usage: {0} (create|extract|list|describe|hash) <OPTIONS> <jmod-file>\n\
 
 error.prefix=Error:
 warn.prefix=Warning:
@@ -37,6 +37,8 @@
 \Main operation modes:
 main.opt.mode.create=\
 \create    - Creates a new jmod archive
+main.opt.mode.extract=\
+\extract   - Extracts all the files from the archive
 main.opt.mode.list=\
 \list      - Prints the names of all the entries
 main.opt.mode.describe=\
@@ -50,6 +52,7 @@
 main.opt.libs=Location of native libraries
 main.opt.cmds=Location of native commands
 main.opt.config=Location of user-editable config files
+main.opt.extractDir=Target directory for extract
 main.opt.dry-run=Dry run of hash mode
 main.opt.exclude=Exclude files matching the supplied comma separated pattern\
 \ list, each element using one the following forms: <glob-pattern>,\
@@ -75,8 +78,9 @@
 
 module.hashes.recorded=Hashes are recorded in module {0}
 
-err.missing.mode=one of create, list, describe, or hash must be specified
-err.invalid.mode=mode must be one of create, list, describe, or hash: {0}
+err.missing.mode=one of create, extract, list, describe, or hash must be specified
+err.invalid.mode=mode must be one of create, extract, list, describe, or hash: {0}
+err.cannot.create.dir=cannot create directory {0}
 err.classpath.must.be.specified=--class-path must be specified
 err.jmod.must.be.specified=jmod-file must be specified
 err.invalid.version=invalid module version {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -43,16 +43,18 @@
 main.opt.config=\u30E6\u30FC\u30B6\u30FC\u304C\u7DE8\u96C6\u53EF\u80FD\u306A\u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240
 main.opt.dry-run=\u30CF\u30C3\u30B7\u30E5\u30FB\u30E2\u30FC\u30C9\u306E\u8A66\u9A13\u7684\u306A\u5B9F\u884C
 main.opt.exclude=\u5404\u8981\u7D20\u304C\u6B21\u306E\u5F62\u5F0F\u306E\u3044\u305A\u308C\u304B\u3092\u4F7F\u7528\u3059\u308B\u3001\u6307\u5B9A\u3055\u308C\u305F\u30AB\u30F3\u30DE\u533A\u5207\u308A\u30D1\u30BF\u30FC\u30F3\u30FB\u30EA\u30B9\u30C8\u306B\u4E00\u81F4\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u3092\u9664\u5916\u3057\u307E\u3059: <glob-pattern>\u3001glob:<glob-pattern>\u307E\u305F\u306Fregex:<regex-pattern>
+main.opt.header-files=\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240
 main.opt.module-version= \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3
 main.opt.main-class=\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9
 main.opt.main-class.arg=class-name
+main.opt.man-pages=man\u30DA\u30FC\u30B8\u306E\u5834\u6240
 main.opt.os-name=\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u540D
 main.opt.os-name.arg=os-name
 main.opt.os-arch=\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u306E\u30A2\u30FC\u30AD\u30C6\u30AF\u30C1\u30E3
 main.opt.os-arch.arg=os-arch
 main.opt.os-version=\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3
 main.opt.os-version.arg=os-version
-main.opt.modulepath=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9
+main.opt.module-path=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9
 main.opt.hash-modules=\u6307\u5B9A\u306E<regex-pattern>\u306B\u4E00\u81F4\u3057\u3001\u76F4\u63A5\u307E\u305F\u306F\u9593\u63A5\u7684\u306B\u4F9D\u5B58\u3057\u3066\u3044\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u7D50\u5408\u3059\u308B\u30CF\u30C3\u30B7\u30E5\u3092\u8A08\u7B97\u304A\u3088\u3073\u8A18\u9332\u3057\u307E\u3059\u3002\u30CF\u30C3\u30B7\u30E5\u306F\u3001\u4F5C\u6210\u3055\u308C\u3066\u3044\u308BJMOD\u30D5\u30A1\u30A4\u30EB\u3001jmod hash\u30B3\u30DE\u30F3\u30C9\u3067\u6307\u5B9A\u3057\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306EJMOD\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30E9JAR\u306B\u8A18\u9332\u3055\u308C\u307E\u3059\u3002
 
 main.opt.cmdfile=\u6307\u5B9A\u3057\u305F\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8AAD\u307F\u53D6\u308A\u307E\u3059
@@ -83,4 +85,7 @@
 warn.invalid.arg=\u7121\u52B9\u306A\u30AF\u30E9\u30B9\u540D\u307E\u305F\u306F\u30D1\u30B9\u540D\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
 warn.no.module.hashes=\u30CF\u30C3\u30B7\u30E5\u304C\u8A18\u9332\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {0}\u306B\u4F9D\u5B58\u3059\u308B\u30CF\u30C3\u30B7\u30E5\u306B\u5BFE\u3057\u3066\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 warn.module.resolution.fail=\u30CF\u30C3\u30B7\u30E5\u304C\u8A18\u9332\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {0}
+warn.ignore.entry=\u30BB\u30AF\u30B7\u30E7\u30F3{1}\u306E\u30A8\u30F3\u30C8\u30EA{0}\u3092\u7121\u8996\u3057\u307E\u3059
+warn.ignore.duplicate.entry=\u30BB\u30AF\u30B7\u30E7\u30F3{1}\u306E\u91CD\u8907\u30A8\u30F3\u30C8\u30EA{0}\u3092\u7121\u8996\u3057\u307E\u3059
 
+
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -43,16 +43,18 @@
 main.opt.config=\u7528\u6237\u53EF\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u7684\u4F4D\u7F6E
 main.opt.dry-run=\u6563\u5217\u6A21\u5F0F\u7684\u6A21\u62DF\u8FD0\u884C
 main.opt.exclude=\u6392\u9664\u4E0E\u6240\u63D0\u4F9B\u9017\u53F7\u5206\u9694\u7684\u6A21\u5F0F\u5217\u8868\u5339\u914D\u7684\u6587\u4EF6, \u6BCF\u4E2A\u5143\u7D20\u4F7F\u7528\u4EE5\u4E0B\u683C\u5F0F\u4E4B\u4E00: <glob \u6A21\u5F0F>, glob:<glob \u6A21\u5F0F> \u6216 regex:<\u6B63\u5219\u8868\u8FBE\u5F0F\u6A21\u5F0F>
+main.opt.header-files=\u6807\u5934\u6587\u4EF6\u7684\u4F4D\u7F6E
 main.opt.module-version= \u6A21\u5757\u7248\u672C
 main.opt.main-class=\u4E3B\u7C7B
 main.opt.main-class.arg=class-name
+main.opt.man-pages=\u5E2E\u52A9\u9875\u7684\u4F4D\u7F6E
 main.opt.os-name=\u64CD\u4F5C\u7CFB\u7EDF\u540D\u79F0
 main.opt.os-name.arg=os-name
 main.opt.os-arch=\u64CD\u4F5C\u7CFB\u7EDF\u4F53\u7CFB\u7ED3\u6784
 main.opt.os-arch.arg=os-arch
 main.opt.os-version=\u64CD\u4F5C\u7CFB\u7EDF\u7248\u672C
 main.opt.os-version.arg=os-version
-main.opt.modulepath=\u6A21\u5757\u8DEF\u5F84
+main.opt.module-path=\u6A21\u5757\u8DEF\u5F84
 main.opt.hash-modules=\u8BA1\u7B97\u548C\u8BB0\u5F55\u6563\u5217, \u4EE5\u5C06\u6253\u5305\u6A21\u5757\u7ED1\u5B9A\u5230\u4E0E\u6307\u5B9A <\u6B63\u5219\u8868\u8FBE\u5F0F\u6A21\u5F0F> \u5339\u914D\u5E76\u76F4\u63A5\u6216\u95F4\u63A5\u4F9D\u8D56\u4E8E\u7684\u6A21\u5757\u3002\u6563\u5217\u8BB0\u5F55\u5728\u6240\u521B\u5EFA\u7684 JMOD \u6587\u4EF6\u4E2D, \u6216\u8005\u8BB0\u5F55\u5728 jmod hash \u547D\u4EE4\u6307\u5B9A\u7684\u6A21\u5757\u8DEF\u5F84\u7684 JMOD \u6587\u4EF6\u6216\u6A21\u5757\u5316 JAR \u4E2D\u3002
 
 main.opt.cmdfile=\u4ECE\u6307\u5B9A\u6587\u4EF6\u8BFB\u53D6\u9009\u9879
@@ -83,4 +85,7 @@
 warn.invalid.arg=\u7C7B\u540D\u65E0\u6548\u6216\u8DEF\u5F84\u540D\u4E0D\u5B58\u5728: {0}
 warn.no.module.hashes=\u672A\u8BB0\u5F55\u4EFB\u4F55\u6563\u5217: \u6CA1\u6709\u4E3A\u4F9D\u8D56\u4E8E {0} \u7684\u6563\u5217\u5904\u7406\u6307\u5B9A\u6A21\u5757
 warn.module.resolution.fail=\u672A\u8BB0\u5F55\u4EFB\u4F55\u6563\u5217: {0}
+warn.ignore.entry=\u6B63\u5728\u5FFD\u7565\u8282 {1} \u4E2D\u7684\u6761\u76EE {0}
+warn.ignore.duplicate.entry=\u6B63\u5728\u5FFD\u7565\u8282 {1} \u4E2D\u7684\u91CD\u590D\u6761\u76EE {0}
 
+
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_de.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_de.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -210,6 +210,7 @@
 rub=Russischer Rubel (neu)
 rur=Russischer Rubel (alt)
 rwf=Ruanda-Franc
+sar=Saudi-Rial
 sbd=Salomonen-Dollar
 scr=Seychellen-Rupie
 sdd=Sudanesischer Dinar
@@ -264,6 +265,7 @@
 xfu=Franz\u00f6sischer UIC-Franc
 xof=CFA Franc (West)
 xpd=Unze Palladium
+xpf=CFP-Franc
 xpt=Unze Platin
 xts=Testw\u00e4hrung
 xxx=Unbekannte W\u00e4hrung
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_it.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_it.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -76,6 +76,7 @@
 aud=Dollaro Australiano
 awg=Fiorino di Aruba
 azm=Manat Azero (1993-2006)
+azn=manat azero
 bam=Marco Conv. Bosnia-Erzegovina
 bbd=Dollaro di Barbados
 bdt=Taka Bangladese
@@ -201,6 +202,7 @@
 pyg=Guarani del Paraguay
 qar=Rial del Qatar
 rol=Leu della Romania
+ron=leu rumeno
 rsd=Dinaro serbo
 rub=Rublo Russo
 rur=Rublo della CSI
@@ -229,7 +231,8 @@
 tnd=Dinaro Tunisino
 top=Pa\u02bbanga di Tonga
 tpe=Escudo di Timor
-trl=Lira Turca
+trl=lira turca (1922-2005)
+try=lira turca
 ttd=Dollaro di Trinidad e Tobago
 twd=Nuovo dollaro taiwanese
 tzs=Scellino della Tanzania
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_sv.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_sv.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -81,6 +81,7 @@
 bbd=Barbados-dollar
 bdt=bangladeshisk taka
 bef=belgisk franc
+bgl=bulgarisk h\u00e5rd lev (1962–1999)
 bgn=bulgarisk ny lev
 bhd=Bahrain-dinar
 bif=burundisk franc
@@ -250,6 +251,7 @@
 vnd=vietnamesisk dong
 vuv=vanuatisk vatu
 wst=v\u00e4stsamoansk tala
+xaf=centralafrikansk franc
 xag=silver
 xau=guld
 xba=europeisk kompositenhet
@@ -259,6 +261,8 @@
 xcd=\u00f6stkaribisk dollar
 xdr=IMF s\u00e4rskild dragningsr\u00e4tt
 xfo=fransk guldfranc
+xfu=internationella j\u00e4rnv\u00e4gsunionens franc
+xof=v\u00e4stafrikansk franc
 xpd=palladium
 xpf=CFP-franc
 xpt=platina
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -216,6 +216,7 @@
 sbd=\u6240\u7f57\u95e8\u7fa4\u5c9b\u5143
 scr=\u585e\u820c\u5c14\u5362\u6bd4
 sdd=\u82cf\u4e39\u7b2c\u7eb3\u5c14
+sdg=\u82cf\u4e39\u9551
 sek=\u745e\u5178\u514b\u6717
 sgd=\u65b0\u52a0\u5761\u5143
 shp=\u5723\u8d6b\u52d2\u62ff\u7fa4\u5c9b\u78c5
--- a/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/Resources_sv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/Resources_sv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -43,7 +43,7 @@
         {"Illegal.option.option", "Otill\u00E5tet alternativ: {0}"},
         {"Usage.policytool.options.", "Syntax: policytool [alternativ]"},
         {".file.file.policy.file.location",
-                "  [-file <fil>]    policyfilens plats"},
+                "  [-file <fil>]    policyfiladress"},
         {"New", "&Nytt"},
         {"Open", "&\u00D6ppna..."},
         {"Save", "S&para"},
--- a/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/Resources_zh_TW.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/Resources_zh_TW.java	Tue Dec 13 02:04:23 2016 +0100
@@ -68,7 +68,7 @@
                 "\u7121\u6CD5\u958B\u555F\u539F\u5247\u6A94\u6848: {0}: {1}"},
         {"Policy.Tool", "\u539F\u5247\u5DE5\u5177"},
         {"Errors.have.occurred.while.opening.the.policy.configuration.View.the.Warning.Log.for.more.information.",
-                "\u958B\u555F\u539F\u5247\u8A18\u7F6E\u6642\u767C\u751F\u932F\u8AA4\u3002\u8ACB\u6AA2\u8996\u8B66\u544A\u8A18\u9304\u4EE5\u53D6\u5F97\u66F4\u591A\u7684\u8CC7\u8A0A"},
+                "\u958B\u555F\u539F\u5247\u7D44\u614B\u6642\u767C\u751F\u932F\u8AA4\u3002\u8ACB\u6AA2\u8996\u8B66\u544A\u8A18\u9304\u4EE5\u53D6\u5F97\u66F4\u591A\u7684\u8CC7\u8A0A"},
         {"Error", "\u932F\u8AA4"},
         {"OK", "\u78BA\u5B9A"},
         {"Status", "\u72C0\u614B"},
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -141,7 +141,6 @@
 javac.err.unmatched.meth={0}\u306B\u9069\u5408\u3059\u308B\u30E1\u30BD\u30C3\u30C9\u304C{1}\u306B\u306F\u3042\u308A\u307E\u305B\u3093\u3002
 javac.err.unmatched.constr={0}\u306B\u9069\u5408\u3059\u308B\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u304C{1}\u306B\u306F\u3042\u308A\u307E\u305B\u3093\u3002
 javac.err.wrong.number.args={0}\u306E\u5F15\u6570\u306E\u6570\u304C\u4E0D\u6B63\u3067\u3059\u3002
-javac.err.wrong.number.args={0}\u306E\u5F15\u6570\u306E\u6570\u304C\u4E0D\u6B63\u3067\u3059\u3002
 javac.err.forward.ref={1}\u3067\u306F{0}\u306B\u524D\u65B9\u53C2\u7167\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002
 javac.err.array.dim.missing=\u914D\u5217\u306E\u5927\u304D\u3055\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
 javac.err.new.abstract={0}\u306Fabstract\u30AF\u30E9\u30B9\u3067\u3059\u3002\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u751F\u6210\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -141,7 +141,6 @@
 javac.err.unmatched.meth=\u5728{1}\u4E2D\u627E\u4E0D\u5230\u4E0E{0}\u5339\u914D\u7684\u65B9\u6CD5\u3002
 javac.err.unmatched.constr=\u5728{1}\u4E2D\u627E\u4E0D\u5230\u4E0E{0}\u5339\u914D\u7684\u6784\u9020\u5668\u3002
 javac.err.wrong.number.args={0}\u4E2D\u7684\u53C2\u6570\u6570\u76EE\u9519\u8BEF\u3002
-javac.err.wrong.number.args={0}\u4E2D\u7684\u53C2\u6570\u6570\u76EE\u9519\u8BEF\u3002
 javac.err.forward.ref=\u65E0\u6CD5\u524D\u5411\u5F15\u7528{1}\u4E2D\u7684{0}\u3002
 javac.err.array.dim.missing=\u7F3A\u5C11\u6570\u7EC4\u7EF4\u3002
 javac.err.new.abstract={0}\u662F\u62BD\u8C61\u7C7B\u3002\u65E0\u6CD5\u5B9E\u4F8B\u5316\u3002
--- a/jdk/test/Makefile	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/Makefile	Tue Dec 13 02:04:23 2016 +0100
@@ -23,272 +23,20 @@
 # questions.
 #
 
-#
-# Makefile to run various jdk tests
-#
-
-.DEFAULT : all
-
-# Empty these to get rid of some default rules
-.SUFFIXES:
-.SUFFIXES: .java
-CO=
-GET=
-
-# Utilities used
-AWK       = awk
-CAT       = cat
-CD        = cd
-CHMOD     = chmod
-CP        = cp
-CUT       = cut
-DIRNAME   = dirname
-ECHO      = echo
-EGREP     = egrep
-EXPAND    = expand
-FIND      = find
-MKDIR     = mkdir
-PWD       = pwd
-SED       = sed
-SORT      = sort
-TEE       = tee
-UNAME     = uname
-UNIQ      = uniq
-WC        = wc
-ZIPEXE    = zip
-
-# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
-UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
-
-# Commands to run on paths to make mixed paths for java on windows
-ifeq ($(UNAME_S), CYGWIN)
-  # Location of developer shared files
-  SLASH_JAVA = J:
-  GETMIXEDPATH = cygpath -m
-else
-  # Location of developer shared files
-  SLASH_JAVA = /java
+default: all
 
-  GETMIXEDPATH=$(ECHO)
-endif
-
-# Root of this test area (important to use full paths in some places)
-TEST_ROOT := $(shell $(PWD))
-
-# Root of all test results
-ifdef TEST_OUTPUT_DIR
-  $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg)
-  ABS_TEST_OUTPUT_DIR := \
-    $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD))
-else
-  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)
-endif
-
-# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
-ifndef PRODUCT_HOME
-  # Try to use images/jdk if it exists
-  ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/jdk
-  PRODUCT_HOME :=                       		\
-    $(shell                             		\
-      if [ -d $(ABS_JDK_IMAGE) ] ; then 		\
-         $(ECHO) "$(ABS_JDK_IMAGE)";    		\
-       else                             		\
-         $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)";		\
-       fi)
-  PRODUCT_HOME := $(PRODUCT_HOME)
-endif
-
-# Expect JPRT to set JPRT_PRODUCT_ARGS (e.g. -server etc.)
-#   Should be passed into 'java' only.
-#   Could include: -d64 -server -client OR any java option
-ifdef JPRT_PRODUCT_ARGS
-  JAVA_ARGS = $(JPRT_PRODUCT_ARGS)
-endif
-
-# Expect JPRT to set JPRT_PRODUCT_VM_ARGS (e.g. -Xcomp etc.)
-#   Should be passed into anything running the vm (java, javac, javadoc, ...).
-ifdef JPRT_PRODUCT_VM_ARGS
-  JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS)
-endif
+NATIVE_TEST_PATH := jdk/jtreg/native
 
-# jtreg -nativepath <dir>
-#
-# Local make tests will be TEST_IMAGE_DIR and JPRT with jprt.use.reg.test.bundle=true
-# should be JPRT_TESTNATIVE_PATH
-ifdef TEST_IMAGE_DIR
-  TESTNATIVE_DIR = $(TEST_IMAGE_DIR)
-else ifdef JPRT_TESTNATIVE_PATH
-  TESTNATIVE_DIR = $(JPRT_TESTNATIVE_PATH)
-endif
-ifdef TESTNATIVE_DIR
-  JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/jdk/jtreg/native")
-endif
-
-# jtreg failure handler config
-ifeq ($(FAILURE_HANDLER_DIR), )
-  ifneq ($(TESTNATIVE_DIR), )
-    FAILURE_HANDLER_DIR := $(TESTNATIVE_DIR)/failure_handler
-  endif
-endif
-ifneq ($(FAILURE_HANDLER_DIR), )
-  FAILURE_HANDLER_DIR_MIXED := $(shell $(GETMIXEDPATH) "$(FAILURE_HANDLER_DIR)")
-  JTREG_FAILURE_HANDLER_OPTIONS := \
-      -timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-      -observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-      -timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \
-      -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver \
-      -timeoutHandlerTimeout:0
-  ifeq ($(UNAME_S), CYGWIN)
-    JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)"
-  endif
-endif
-
-# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
-ifdef JPRT_ARCHIVE_BUNDLE
-  ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
-else
-  ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
-endif
-
-# How to create the test bundle (pass or fail, we want to create this)
-#   Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
-ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`     \
-	           && $(CD) $(ABS_TEST_OUTPUT_DIR)             \
-	           && $(CHMOD) -R a+r . \
-	           && $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . )
+USE_FAILURE_HANDLER := true
 
-# important results files
-SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
-STATS_TXT_NAME = Stats.txt
-STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)")
-RUNLIST   = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt")
-PASSLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt")
-FAILLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt")
-EXITCODE  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt")
-
-TESTEXIT = \
-  if [ ! -s $(EXITCODE) ] ; then \
-    $(ECHO) "ERROR: EXITCODE file not filled in."; \
-    $(ECHO) "1" > $(EXITCODE); \
-  fi ; \
-  testExitCode=`$(CAT) $(EXITCODE)`; \
-  $(ECHO) "EXIT CODE: $${testExitCode}"; \
-  exit $${testExitCode}
+TREAT_EXIT_CODE_1_AS_0 := true
 
-BUNDLE_UP_AND_EXIT = \
-( \
-  jtregExitCode=$$? && \
-  _summary="$(SUMMARY_TXT)"; \
-  if [ $${jtregExitCode} = 1 ] ; then \
-    jtregExitCode=0; \
-  fi; \
-  $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
-  $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
-  if [ -r "$${_summary}" ] ; then \
-    $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
-    $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
-    $(EGREP) ' Passed\.' $(RUNLIST) \
-      | $(EGREP) -v ' Error\.' \
-      | $(EGREP) -v ' Failed\.' > $(PASSLIST); \
-    ( $(EGREP) ' Failed\.' $(RUNLIST); \
-      $(EGREP) ' Error\.' $(RUNLIST); \
-      $(EGREP) -v ' Passed\.' $(RUNLIST) ) \
-      | $(SORT) | $(UNIQ) > $(FAILLIST); \
-    if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \
-      $(EXPAND) $(FAILLIST) \
-        | $(CUT) -d' ' -f1 \
-        | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \
-      if [ $${jtregExitCode} = 0 ] ; then \
-        jtregExitCode=1; \
-      fi; \
-    fi; \
-    runc="`$(CAT) $(RUNLIST)      | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    passc="`$(CAT) $(PASSLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    failc="`$(CAT) $(FAILLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    exclc="FIXME CODETOOLS-7900176"; \
-    $(ECHO) "TEST STATS: name=$(UNIQUE_DIR)  run=$${runc}  pass=$${passc}  fail=$${failc}" \
-      >> $(STATS_TXT); \
-  else \
-    $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
-  fi; \
-  if [ -f $(STATS_TXT) ] ; then \
-    $(CAT) $(STATS_TXT); \
-  fi; \
-  $(ZIP_UP_RESULTS) ; \
-  $(TESTEXIT) \
-)
-
-################################################################
+include ../../test/TestCommon.gmk
 
 # Default make rule (runs default jdk tests)
 all: jdk_default
 	@$(ECHO) "Testing completed successfully"
 
-# Prep for output
-# Change execute permissions on shared library files.
-# Files in repositories should never have execute permissions, but
-# there are some tests that have pre-built shared libraries, and these
-# windows dll files must have execute permission. Adding execute
-# permission may happen automatically on windows when using certain
-# versions of mercurial but it cannot be guaranteed. And blindly
-# adding execute permission might be seen as a mercurial 'change', so
-# we avoid adding execute permission to repository files. But testing
-# from a plain source tree needs the chmod a+rx. Applying the chmod to
-# all shared libraries not just dll files. And with CYGWIN and sshd
-# service, you may need CYGWIN=ntsec for this to work.
-prep:
-	@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
-	@$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`
-	@if [ ! -d $(TEST_ROOT)/../.hg ] ; then                          \
-	  $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \)  \
-	        -exec $(CHMOD) a+rx {} \; ;                             \
-        fi
-
-# Cleanup
-clean:
-	@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
-	@$(RM) $(ARCHIVE_BUNDLE)
-
-################################################################
-
-# jtreg tests
-
-# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
-ifndef JT_HOME
-  JT_HOME = $(SLASH_JAVA)/re/jtreg/4.2/promoted/latest/binaries/jtreg
-  ifdef JPRT_JTREG_HOME
-    JT_HOME = $(JPRT_JTREG_HOME)
-  endif
-endif
-
-# Problematic tests to be excluded
-PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt))
-
-# Create exclude list for this platform and arch
-ifdef NO_EXCLUDES
-  JTREG_EXCLUSIONS =
-else
-  JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%)
-endif
-
-# convert list of directories to dos paths
-define MixedDirs
-$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}"))
-endef
-
-define SummaryInfo
-$(ECHO) "########################################################"
-$(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME))
-$(ECHO) "########################################################"
-endef
-
 # ------------------------------------------------------------------
 
 jdk_% core_% svc_%:
@@ -296,82 +44,3 @@
 	for each in $@; do \
 	        $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \
 	done
-
-# ------------------------------------------------------------------
-
-# When called from JPRT the TESTDIRS variable is set to the jtreg tests to run
-ifdef TESTDIRS
-  TEST_SELECTION = $(TESTDIRS)
-endif
-
-ifdef CONCURRENCY
-  JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
-endif
-ifdef EXTRA_JTREG_OPTIONS
-  JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
-endif
-
-# Default JTREG to run
-JTREG = $(JT_HOME)/bin/jtreg
-# run in agentvm mode
-JTREG_BASIC_OPTIONS += -agentvm
-# Only run automatic tests
-JTREG_BASIC_OPTIONS += -a
-# Always turn on assertions
-JTREG_ASSERT_OPTION = -ea -esa
-JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION)
-# jtreg verbosity setting
-JTREG_VERBOSE ?= fail,error,time
-JTREG_BASIC_OPTIONS += $(if $(JTREG_VERBOSE),-v:$(JTREG_VERBOSE))
-# Retain all files for failing tests
-JTREG_BASIC_OPTIONS += -retain:fail,error
-# Ignore tests are not run and completely silent about it
-JTREG_IGNORE_OPTION = -ignore:quiet
-JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
-# Multiple by 4 the timeout numbers
-JTREG_TIMEOUT_OPTION =  -timeoutFactor:4
-JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
-# Set the max memory for jtreg control vm
-JTREG_MEMORY_OPTION = -J-Xmx512m
-JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
-# Give tests access to JT_JAVA, see JDK-8141609
-JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
-# Set other vm and test options
-JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
-# Set the GC options for test vms
-#JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
-#JTREG_TEST_OPTIONS += $(JTREG_GC_OPTION)
-# Set the max memory for jtreg target test vms
-JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m
-JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
-
-# Make sure jtreg exists
-$(JTREG): $(JT_HOME)
-
-# Run jtreg
-jtreg_tests: prep $(PRODUCT_HOME) $(JTREG)
-	(                                                                    \
-	  ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)");                   \
-            export JT_HOME;                                                  \
-            $(shell $(GETMIXEDPATH) "$(JTREG)")                              \
-              $(JTREG_BASIC_OPTIONS)                                         \
-              -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport")  \
-              -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork")    \
-              -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                \
-              $(JTREG_NATIVE_PATH)                                           \
-              $(JTREG_FAILURE_HANDLER_OPTIONS)                               \
-              $(JTREG_EXCLUSIONS)                                            \
-              $(JTREG_TEST_OPTIONS)                                          \
-              $(TEST_SELECTION)                                                    \
-	  ) ;                                                                \
-	  $(BUNDLE_UP_AND_EXIT)                                              \
-	) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT)
-
-PHONY_LIST += jtreg_tests
-
-################################################################
-
-# Phony targets (e.g. these are not filenames)
-.PHONY: all clean prep $(PHONY_LIST)
-
-################################################################
--- a/jdk/test/ProblemList.txt	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/ProblemList.txt	Tue Dec 13 02:04:23 2016 +0100
@@ -171,11 +171,7 @@
 
 java/net/DatagramSocket/SendDatagramToBadAddress.java           7143960 macosx-all
 
-java/net/httpclient/SplitResponse.java                          8157533 generic-all 
-
-java/net/httpclient/http2/BasicTest.java                        8157408 linux-all
-java/net/httpclient/http2/ErrorTest.java                        8158127 solaris-all,windows-all
-java/net/httpclient/http2/TLSConnection.java                    8157482 macosx-all
+java/net/httpclient/TimeoutOrdering.java                        8170940 solaris-all,windows-all
 
 ############################################################################
 
@@ -223,6 +219,8 @@
 
 sun/security/ssl/SSLSocketImpl/AsyncSSLSocketClose.java         8161232 macosx-all
 
+sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java  8171043 windows-all
+
 ############################################################################
 
 # jdk_sound
@@ -265,6 +263,8 @@
 tools/jimage/JImageListTest.java                                8169713 generic-all
 tools/jimage/JImageVerifyTest.java                              8169713 generic-all
 
+tools/jlink/ModuleNamesOrderTest.java                           8171070 generic-all
+
 ############################################################################
 
 # jdk_jdi
@@ -291,6 +291,7 @@
 
 java/util/BitSet/BitSetStreamTest.java                          8079538 generic-all
 
+
 ############################################################################
 
 # jdk_instrument
--- a/jdk/test/TEST.groups	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/TEST.groups	Tue Dec 13 02:04:23 2016 +0100
@@ -158,7 +158,6 @@
 
 jdk_net = \
     java/net \
-    -java/net/httpclient \
     com/sun/net/httpserver \
     sun/net \
     jdk/net
--- a/jdk/test/java/io/Serializable/serialFilter/SerialFilterTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/io/Serializable/serialFilter/SerialFilterTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -99,16 +99,6 @@
     @DataProvider(name="InvalidPatterns")
     static Object[][] invalidPatterns() {
         return new Object [][] {
-                {"maxrefs=-1"},
-                {"maxdepth=-1"},
-                {"maxbytes=-1"},
-                {"maxarray=-1"},
-                {"xyz=0"},
-                {"xyz=-1"},
-                {"maxrefs=0xabc"},
-                {"maxrefs=abc"},
-                {"maxrefs="},
-                {"maxrefs=+"},
                 {".*"},
                 {".**"},
                 {"!"},
@@ -121,11 +111,32 @@
     @DataProvider(name="Limits")
     static Object[][] limits() {
         // The numbers are arbitrary > 1
-        return new Object[][]{
+        return new Object[][] {
+                {"maxrefs", 1},     // 0 is tested as n-1
                 {"maxrefs", 10},
                 {"maxdepth", 5},
                 {"maxbytes", 100},
                 {"maxarray", 16},
+                {"maxbytes", Long.MAX_VALUE},
+        };
+    }
+
+    @DataProvider(name="InvalidLimits")
+    static Object[][] invalidLimits() {
+        return new Object[][] {
+                {"maxrefs=-1"},
+                {"maxdepth=-1"},
+                {"maxbytes=-1"},
+                {"maxarray=-1"},
+                {"xyz=0"},
+                {"xyz=-1"},
+                {"maxrefs=0xabc"},
+                {"maxrefs=abc"},
+                {"maxrefs="},
+                {"maxrefs=+"},
+                {"maxbytes=-1"},
+                {"maxbytes=9223372036854775808"},
+                {"maxbytes=-9223372036854775807"},
         };
     }
 
@@ -305,7 +316,7 @@
      * @param value a test value
      */
     @Test(dataProvider="Limits")
-    static void testLimits(String name, int value) {
+    static void testLimits(String name, long value) {
         Class<?> arrayClass = new int[0].getClass();
         String pattern = String.format("%s=%d;%s=%d", name, value, name, value - 1);
         ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
@@ -320,6 +331,21 @@
     }
 
     /**
+     * Test invalid limits.
+     * Construct a filter with the limit, it should throw IllegalArgumentException.
+     * @param pattern a pattern to test
+     */
+    @Test(dataProvider="InvalidLimits", expectedExceptions=java.lang.IllegalArgumentException.class)
+    static void testInvalidLimits(String pattern) {
+        try {
+            ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
+        } catch (IllegalArgumentException iae) {
+            System.out.printf("    success exception: %s%n", iae);
+            throw iae;
+        }
+    }
+
+    /**
      * Test that returning null from a filter causes deserialization to fail.
      */
     @Test(expectedExceptions=InvalidClassException.class)
@@ -332,7 +358,7 @@
                 }
             });
         } catch (InvalidClassException ice) {
-            System.out.printf("Success exception: %s%n", ice);
+            System.out.printf("    success exception: %s%n", ice);
             throw ice;
         }
     }
@@ -606,7 +632,7 @@
             }
             return array;
         } else if (pattern.startsWith("maxarray=")) {
-            return allowed ? new int[(int)value] : new int[(int)value+1];
+                return allowed ? new int[(int)value] : new int[(int)value+1];
         }
         Assert.fail("Object could not be generated for pattern: "
                 + pattern
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Class/attributes/ClassAttributesTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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 8170595
+ * @summary Checks Class.isAnonymousClass, isMemberClass and isLocalClass
+ *          attributes
+ */
+
+public class ClassAttributesTest {
+
+    class NestedClass {}
+
+    static int test(Class<?> clazz, boolean anonymous, boolean local, boolean member) {
+        if (clazz.isAnonymousClass() != anonymous) {
+            System.err.println("Unexpected isAnonymousClass value for " +
+                               clazz.getName() + " expected: " + anonymous +
+                               " got: " + (!anonymous));
+            return 1;
+        }
+        if (clazz.isLocalClass() != local) {
+            System.err.println("Unexpected isLocalClass value for " +
+                               clazz.getName() + " expected: " + local +
+                               " got: " + (!local));
+            return 1;
+        }
+        if (clazz.isMemberClass() != member) {
+            System.err.println("Unexpected isMemberClass status for " +
+                               clazz.getName() + " expected: " + member +
+                               " got: " + (!member));
+            return 1;
+        }
+        return 0;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        class LocalClass {}
+        Cloneable clone = new Cloneable() {};
+        Runnable lambda = () -> System.out.println("run");
+
+        failures += test(ClassAttributesTest.class,       false, false, false);
+        failures += test(NestedClass.class,               false, false, true);
+        failures += test(LocalClass.class,                false, true,  false);
+        failures += test(clone.getClass(),                true,  false, false);
+
+        // Lambdas may be VM anonymous classes, but are named, non-local classes
+        // in this sense
+        failures += test(lambda.getClass(),               false, false, false);
+
+        if (failures != 0)
+            throw new RuntimeException("Test failed with " + failures  + " failures.");
+    }
+}
--- a/jdk/test/java/lang/System/LoggerFinder/internal/SystemLoggerInPlatformLoader/SystemLoggerInPlatformLoader.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/SystemLoggerInPlatformLoader/SystemLoggerInPlatformLoader.java	Tue Dec 13 02:04:23 2016 +0100
@@ -28,9 +28,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Layer;
 import java.lang.reflect.Method;
 
-/**
+/*
  * @test 8163162
  * @summary Checks that LazyLoggers are returned for System.Logger instances
  *          created by modules in the platform class loader.
@@ -98,25 +99,36 @@
     }
 
     public static void main(String[] args) {
-        System.Logger splogger = getSystemLogger("bar"); // for a platform class
-        System.Logger slogger = System.getLogger("bar"); // for an application class
-        if (slogger == splogger) {
+        System.Logger platformLogger = getSystemLogger("bar"); // for a platform class
+        System.Logger appLogger = System.getLogger("bar"); // for an application class
+        if (appLogger == platformLogger) {
             throw new RuntimeException("Same loggers");
         }
-        Class sploggerType = splogger.getClass();
-        System.out.println("splogger: " + sploggerType);
-        if (!sploggerType.getSimpleName().equals("JdkLazyLogger")) {
-            throw new RuntimeException(sploggerType.getSimpleName()
-                      + ": unexpected class for splogger"
+        Class<?> platformLoggerType = platformLogger.getClass();
+        System.out.println("platformLogger: " + platformLoggerType);
+        boolean simpleConsoleOnly = !Layer.boot().findModule("java.logging").isPresent();
+        if (simpleConsoleOnly) {
+            /* Happens if the test is called with custom JDK without java.logging module
+               or in case usage commandline option --limit-modules java.base */
+            if (!platformLoggerType.getSimpleName().equals("SimpleConsoleLogger")) {
+                throw new RuntimeException(platformLoggerType.getSimpleName()
+                      + ": unexpected class for platform logger"
+                      + " (expected a simple console logger class)");
+            }
+        } else {
+            if (!platformLoggerType.getSimpleName().equals("JdkLazyLogger")) {
+                throw new RuntimeException(platformLoggerType.getSimpleName()
+                      + ": unexpected class for platform logger"
                       + " (expected a lazy logger for a platform class)");
-        }
-        Class sloggerType = slogger.getClass();
-        System.out.println("slogger: " + sloggerType);
-        if (sloggerType.equals(sploggerType)) {
-            throw new RuntimeException(sloggerType
-                      + ": unexpected class for slogger"
+            }
+            Class<?> appLoggerType = appLogger.getClass();
+            System.out.println("appLogger: " + appLoggerType);
+            if (appLoggerType.equals(platformLoggerType)) {
+                throw new RuntimeException(appLoggerType
+                      + ": unexpected class for application logger"
                       + " (a lazy logger was not expected"
                       + " for a non platform class)");
+            }
         }
     }
 }
--- a/jdk/test/java/net/InetAddress/ptr/Lookup.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/InetAddress/ptr/Lookup.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,35 +22,79 @@
  */
 
 /*
- *
+ * Lookup/reverse lookup class for regression test 4773521
+ * @test
+ * @bug 4773521
+ * @summary Test that reverse lookups of IPv4 addresses work when IPv6
+ *          is enabled
+ * @library /test/lib
+ * @build jdk.test.lib.JDKToolFinder
+ *        jdk.test.lib.process.OutputAnalyzer
+ *        Lookup
+ * @run main Lookup root
  *
- * Lookup/reverse lookup class for regression test 4773521 - see
- * lookup.sh for details.
  */
+import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.List;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.OutputAnalyzer;
 
 public class Lookup {
-    public static void main(String args[]) throws UnknownHostException {
+    private static final String HOST = "icann.org";
+    private static final String SKIP = "SKIP";
+    private static final String CLASS_PATH = System.getProperty(
+            "test.class.path");
+
+    public static void main(String args[]) throws IOException {
+        String addr = null;
+        String ipv4Name = null;
+        if (args.length == 0) {
+            // First check that host resolves to IPv4 address
+            try {
+                InetAddress ia = InetAddress.getByName(HOST);
+                addr = ia.getHostAddress();
+            } catch (UnknownHostException e) {
+                System.out.print(SKIP);
+                return;
+            }
+        } else {
+            String tmp = lookupWithIPv4Prefer();
+            System.out.println("IPv4 lookup results: [" + tmp + "]");
+            if (SKIP.equals(tmp)) {
+                System.out.println(HOST + " can't be resolved - test skipped.");
+                return;
+            }
+
+            String[] strs = tmp.split(":");
+            addr = strs[0];
+            ipv4Name = strs[1];
+        }
 
         // reverse lookup
-
-        if (args[0].equals("-q=PTR")) {
-            InetAddress ia = InetAddress.getByName(args[1]);
-            System.out.println(ia.getHostName());
+        InetAddress ia = InetAddress.getByName(addr);
+        String name = ia.getHostName();
+        if (args.length == 0) {
+            System.out.print(addr + ":" + name);
             return;
+        } else {
+            System.out.println("(default) " + addr + "--> " + name);
+            if (!ipv4Name.equals(name)) {
+                throw new RuntimeException("Mismatch between default"
+                        + " and java.net.preferIPv4Stack=true results");
+            }
         }
-
-        // lookup address
-
-        String addr;
-        if (args[0].equals("-q=A")) {
-            addr = args[1];
-        } else {
-            addr = args[0];
-        }
-        InetAddress ia = InetAddress.getByName(args[1]);
-        System.out.println(ia.getHostAddress());
     }
 
+    static String lookupWithIPv4Prefer() throws IOException {
+        String java = JDKToolFinder.getTestJDKTool("java");
+        String testClz = Lookup.class.getName();
+        List<String> cmd = List.of(java, "-Djava.net.preferIPv4Stack=true",
+                "-cp", CLASS_PATH, testClz);
+        System.out.println("Executing: " + cmd);
+        return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput();
+    }
 }
+
--- a/jdk/test/java/net/InetAddress/ptr/lookup.sh	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-
-# @test
-# @bug 4773521
-# @build Lookup
-# @run shell lookup.sh
-# @summary Test that reverse lookups of IPv4 addresses work when IPv6
-#          is enabled. 
-
-# The host that we try to resolve
-
-HOST=javaweb.sfbay.sun.com
-
-CLASSPATH=${TESTCLASSES}
-export CLASSPATH
-JAVA="${TESTJAVA}/bin/java"
-
-
-# First check that host resolves to IPv4 address.
-
-echo ''
-ADDR=`$JAVA -Djava.net.preferIPv4Stack=true Lookup -q=A $HOST`
-if [ $? != 0 ]; then
-    echo "$HOST can't be resolved - test skipped."
-    exit 0
-fi
-echo "$HOST --> $ADDR"
-
-
-# IPv4 reverse lookup
-echo ''
-OUT1=`$JAVA ${TESTVMOPTS} -Djava.net.preferIPv4Stack=true Lookup -q=PTR $ADDR`
-echo "(IPv4) $ADDR --> $OUT1"
-
-
-# reverse lookup (default)
-echo ''
-OUT2=`$JAVA ${TESTVMOPTS} Lookup -q=PTR $ADDR`
-echo "(default) $ADDR --> $OUT2"
-
-
-# Compare results
-if [ "$OUT1" != "$OUT2" ]; then
-    echo ''
-    echo "Mistmatch between default and java.net.preferIPv4Stack=true results"
-    exit 1
-fi
-
--- a/jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, 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
@@ -22,21 +22,64 @@
  */
 
 /*
- * Test run from script, AcceptCauseFileDescriptorLeak.sh
  * author Edward Wang
+ *
+ * @test
+ * @bug 6368984
+ * @summary Configuring unconnected Socket before passing to implAccept
+ *          can cause fd leak
+ * @requires (os.family != "windows")
+ * @library /test/lib
+ * @build jdk.test.lib.JDKToolFinder
+ *        jdk.test.lib.process.OutputAnalyzer
+ *        AcceptCauseFileDescriptorLeak
+ * @run main/othervm AcceptCauseFileDescriptorLeak root
  */
 
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.util.List;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.OutputAnalyzer;
 
 public class AcceptCauseFileDescriptorLeak {
     private static final int REPS = 2048;
+    private static final int THRESHOLD = 1024;
 
     public static void main(String[] args) throws Exception {
+        if (args.length != 0) {
+            OutputAnalyzer analyzer = execCmd("ulimit -n -H");
+            String output = analyzer.getOutput();
+            if (output == null || output.length() == 0) {
+                throw new RuntimeException("\"ulimit -n -H\" output nothing"
+                        + " and its exit code is " + analyzer.getExitValue());
+            } else {
+                output = output.trim();
+                // Set max open file descriptors to 1024
+                // if it is unlimited or greater than 1024,
+                // otherwise just do test directly
+                if ("unlimited".equals(output)
+                        || Integer.valueOf(output) > THRESHOLD) {
+                    analyzer = execCmd("ulimit -n " + THRESHOLD + "; "
+                            + composeJavaTestStr());
+                    System.out.println("Output: ["
+                            + analyzer.getOutput() + "]");
+                    int rc = analyzer.getExitValue();
+                    if (rc != 0) {
+                        throw new RuntimeException(
+                                "Unexpected exit code: " + rc);
+                    }
+                    return;
+                }
+            }
+        }
+
         final ServerSocket ss = new ServerSocket(0) {
             public Socket accept() throws IOException {
-                Socket s = new Socket() { };
+                Socket s = new Socket() {
+                };
                 s.setSoTimeout(10000);
                 implAccept(s);
                 return s;
@@ -54,10 +97,33 @@
             }
         });
         t.start();
-        for (int i = 0; i < REPS; i++) {
-            ss.accept().close();
+        try {
+            for (int i = 0; i < REPS; i++) {
+                ss.accept().close();
+            }
+        } finally {
+            ss.close();
         }
-        ss.close();
         t.join();
     }
+
+    /**
+     * Execute command with shell
+     *
+     * @param  command
+     * @return OutputAnalyzer
+     * @throws IOException
+     */
+    static OutputAnalyzer execCmd(String command) throws IOException {
+        List<String> cmd = List.of("sh", "-c", command);
+        System.out.println("Executing: " + cmd);
+        ProcessBuilder pb = new ProcessBuilder(cmd);
+        return new OutputAnalyzer(pb.start());
+    }
+
+    static String composeJavaTestStr() {
+        return JDKToolFinder.getTestJDKTool("java") + " "
+                + AcceptCauseFileDescriptorLeak.class.getName();
+    }
 }
+
--- a/jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.sh	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#
-# Copyright (c) 2010, 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 6368984
-# @summary configuring unconnected Socket before passing to implAccept can cause fd leak
-# @build AcceptCauseFileDescriptorLeak
-# @run shell AcceptCauseFileDescriptorLeak.sh
-
-OS=`uname -s`
-case "$OS" in
-    Windows_* | CYGWIN* )
-        echo "ulimit not on Windows"
-        exit 0
-        ;;
-    * )
-        CLASSPATH=${TESTCLASSES}:${TESTSRC}
-        ;;
-esac
-export CLASSPATH
-
-# hard limit needs to be less than 1024 for this bug
-NOFILES=`ulimit -n -H`
-if [ "$NOFILES" = "unlimited" ] || [ $NOFILES -ge 1024 ]; then
-    ulimit -n 1024
-fi
-
-${TESTJAVA}/bin/java ${TESTVMOPTS} AcceptCauseFileDescriptorLeak
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/SocketOption/MinimumRcvBufferSize.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8170920
+ * @run main MinimumRcvBufferSize
+ */
+
+import java.nio.channels.*;
+import java.net.*;
+
+public class MinimumRcvBufferSize {
+
+    public static void main(String args[]) throws Exception {
+        boolean error = false;
+        ServerSocketChannel channel = ServerSocketChannel.open();
+        int before = channel.getOption(StandardSocketOptions.SO_RCVBUF);
+        channel.setOption(StandardSocketOptions.SO_RCVBUF, Integer.MAX_VALUE);
+        int after = channel.getOption(StandardSocketOptions.SO_RCVBUF);
+        if (before > after) {
+            System.err.println("Test failed: SO_RCVBUF");
+            error = true;
+        }
+
+        SocketChannel channel1 = SocketChannel.open();
+        before = channel1.getOption(StandardSocketOptions.SO_SNDBUF);
+        channel1.setOption(StandardSocketOptions.SO_SNDBUF, Integer.MAX_VALUE);
+        after = channel1.getOption(StandardSocketOptions.SO_SNDBUF);
+        if (before > after) {
+            System.err.println("Test failed: SO_SNDBUF");
+            error = true;
+        }
+        if (error)
+            throw new RuntimeException("Test failed");
+    }
+}
--- a/jdk/test/java/net/httpclient/APIErrors.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/APIErrors.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          java.logging
  *          jdk.httpserver
  * @library /lib/testlibrary/
@@ -33,8 +33,8 @@
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
  * @run main/othervm APIErrors
+ * @summary  Basic checks for appropriate errors/exceptions thrown from the API
  */
-//package javaapplication16;
 
 import com.sun.net.httpserver.HttpContext;
 import com.sun.net.httpserver.HttpHandler;
@@ -45,45 +45,43 @@
 import java.net.PasswordAuthentication;
 import java.net.ProxySelector;
 import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
 import java.util.function.Supplier;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
 
-/**
- * Does stupid things with API, to check appropriate errors/exceptions thrown
- */
 public class APIErrors {
 
-    static HttpServer s1 = null;
-    static ExecutorService executor = null;
-    static int port;
-    static HttpClient client;
-    static String httproot, fileuri, fileroot;
+    static ExecutorService serverExecutor = Executors.newCachedThreadPool();
+    static String httproot, fileuri;
     static List<HttpClient> clients = new LinkedList<>();
 
     public static void main(String[] args) throws Exception {
-        initServer();
-        fileroot = System.getProperty("test.src") + "/docs";
+        HttpServer server = createServer();
+
+        int port = server.getAddress().getPort();
+        System.out.println("HTTP server port = " + port);
 
-        client = HttpClient.create().build();
+        httproot = "http://127.0.0.1:" + port + "/files/";
+        fileuri = httproot + "foo.txt";
 
-        clients.add(HttpClient.getDefault());
+        HttpClient client = HttpClient.newHttpClient();
 
         try {
             test1();
             test2();
-            test3();
+            //test3();
         } finally {
-            s1.stop(0);
-            executor.shutdownNow();
-            for (HttpClient client : clients)
-                client.executorService().shutdownNow();
+            server.stop(0);
+            serverExecutor.shutdownNow();
+            for (HttpClient c : clients)
+                ((ExecutorService)c.executor()).shutdownNow();
         }
     }
 
@@ -100,12 +98,13 @@
     // HttpClient.Builder
     static void test1() throws Exception {
         System.out.println("Test 1");
-        HttpClient.Builder cb = HttpClient.create();
-        InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 5000);
+        HttpClient.Builder cb = HttpClient.newBuilder();
         TestKit.assertThrows(IllegalArgumentException.class, () -> cb.priority(-1));
+        TestKit.assertThrows(IllegalArgumentException.class, () -> cb.priority(0));
+        TestKit.assertThrows(IllegalArgumentException.class, () -> cb.priority(257));
         TestKit.assertThrows(IllegalArgumentException.class, () -> cb.priority(500));
         TestKit.assertNotThrows(() -> cb.priority(1));
-        TestKit.assertNotThrows(() -> cb.priority(255));
+        TestKit.assertNotThrows(() -> cb.priority(256));
         TestKit.assertNotThrows(() -> {
             clients.add(cb.build());
             clients.add(cb.build());
@@ -114,14 +113,14 @@
 
     static void test2() throws Exception {
         System.out.println("Test 2");
-        HttpClient.Builder cb = HttpClient.create();
+        HttpClient.Builder cb = HttpClient.newBuilder();
         InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 5000);
         cb.proxy(ProxySelector.of(addr));
         HttpClient c = cb.build();
         clients.add(c);
-        checkNonNull(()-> {return c.executorService();});
-        assertTrue(()-> {return c.followRedirects() == HttpClient.Redirect.NEVER;});
-        assertTrue(()-> {return !c.authenticator().isPresent();});
+        checkNonNull(()-> c.executor());
+        assertTrue(()-> c.followRedirects() == HttpClient.Redirect.NEVER);
+        assertTrue(()-> !c.authenticator().isPresent());
     }
 
     static URI accessibleURI() {
@@ -129,41 +128,40 @@
     }
 
     static HttpRequest request() {
-        return HttpRequest.create(accessibleURI())
-                .GET();
+        return HttpRequest.newBuilder(accessibleURI()).GET().build();
     }
 
-    static void test3() throws Exception {
-        System.out.println("Test 3");
-        TestKit.assertThrows(IllegalStateException.class, ()-> {
-            try {
-                HttpRequest r1 = request();
-                HttpResponse resp = r1.response();
-                HttpResponse resp1 = r1.response();
-            } catch (IOException |InterruptedException e) {
-                throw new RuntimeException(e);
-            }
-        });
-
-        TestKit.assertThrows(IllegalStateException.class, ()-> {
-            try {
-                HttpRequest r1 = request();
-                HttpResponse resp = r1.response();
-                HttpResponse resp1 = r1.responseAsync().get();
-            } catch (IOException |InterruptedException | ExecutionException e) {
-                throw new RuntimeException(e);
-            }
-        });
-        TestKit.assertThrows(IllegalStateException.class, ()-> {
-            try {
-                HttpRequest r1 = request();
-                HttpResponse resp1 = r1.responseAsync().get();
-                HttpResponse resp = r1.response();
-            } catch (IOException |InterruptedException | ExecutionException e) {
-                throw new RuntimeException(e);
-            }
-        });
-    }
+//    static void test3() throws Exception {
+//        System.out.println("Test 3");
+//        TestKit.assertThrows(IllegalStateException.class, ()-> {
+//            try {
+//                HttpRequest r1 = request();
+//                HttpResponse<Object> resp = r1.response(discard(null));
+//                HttpResponse<Object> resp1 = r1.response(discard(null));
+//            } catch (IOException |InterruptedException e) {
+//                throw new RuntimeException(e);
+//            }
+//        });
+//
+//        TestKit.assertThrows(IllegalStateException.class, ()-> {
+//            try {
+//                HttpRequest r1 = request();
+//                HttpResponse<Object> resp = r1.response(discard(null));
+//                HttpResponse<Object> resp1 = r1.responseAsync(discard(null)).get();
+//            } catch (IOException |InterruptedException | ExecutionException e) {
+//                throw new RuntimeException(e);
+//            }
+//        });
+//        TestKit.assertThrows(IllegalStateException.class, ()-> {
+//            try {
+//                HttpRequest r1 = request();
+//                HttpResponse<Object> resp1 = r1.responseAsync(discard(null)).get();
+//                HttpResponse<Object> resp = r1.response(discard(null));
+//            } catch (IOException |InterruptedException | ExecutionException e) {
+//                throw new RuntimeException(e);
+//            }
+//        });
+//    }
 
     static class Auth extends java.net.Authenticator {
         int count = 0;
@@ -180,24 +178,16 @@
         }
     }
 
-    public static void initServer() throws Exception {
-        String root = System.getProperty ("test.src")+ "/docs";
-        InetSocketAddress addr = new InetSocketAddress (0);
-        s1 = HttpServer.create (addr, 0);
-        if (s1 instanceof HttpsServer) {
+    static HttpServer createServer() throws Exception {
+        HttpServer s = HttpServer.create(new InetSocketAddress(0), 0);
+        if (s instanceof HttpsServer)
             throw new RuntimeException ("should not be httpsserver");
-        }
-        HttpHandler h = new FileServerHandler(root);
 
-        HttpContext c1 = s1.createContext("/files", h);
+        String root = System.getProperty("test.src") + "/docs";
+        s.createContext("/files", new FileServerHandler(root));
+        s.setExecutor(serverExecutor);
+        s.start();
 
-        executor = Executors.newCachedThreadPool();
-        s1.setExecutor (executor);
-        s1.start();
-
-        port = s1.getAddress().getPort();
-        System.out.println("HTTP server port = " + port);
-        httproot = "http://127.0.0.1:" + port + "/files/";
-        fileuri = httproot + "foo.txt";
+        return s;
     }
 }
--- a/jdk/test/java/net/httpclient/BasicAuthTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/BasicAuthTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -4,9 +4,7 @@
  *
  * This code is free software; you can redistribute 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.
+ * 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
@@ -26,7 +24,7 @@
 /**
  * @test
  * @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          jdk.httpserver
  * @run main/othervm BasicAuthTest
  * @summary Basic Authentication Test
@@ -43,10 +41,12 @@
 import java.net.InetSocketAddress;
 import java.net.PasswordAuthentication;
 import java.net.URI;
-import java.net.http.*;
+import jdk.incubator.http.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import static java.nio.charset.StandardCharsets.US_ASCII;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
 public class BasicAuthTest {
 
@@ -67,43 +67,39 @@
         serverContext.setAuthenticator(sa);
         server.setExecutor(e);
         server.start();
-        HttpClient client = HttpClient.create()
+        HttpClient client = HttpClient.newBuilder()
                                       .authenticator(ca)
                                       .build();
 
         try {
             URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/test/foo");
-            HttpRequest req = client.request(uri).GET();
+            HttpRequest req = HttpRequest.newBuilder(uri).GET().build();
 
-            HttpResponse resp = req.response();
-            ok = resp.statusCode() == 200 &&
-                    resp.body(HttpResponse.asString()).equals(RESPONSE);
+            HttpResponse resp = client.send(req, asString());
+            ok = resp.statusCode() == 200 && resp.body().equals(RESPONSE);
 
             if (!ok || ca.count != 1)
                 throw new RuntimeException("Test failed");
 
             // repeat same request, should succeed but no additional authenticator calls
 
-            req = client.request(uri).GET();
-            resp = req.response();
-            ok = resp.statusCode() == 200 &&
-                    resp.body(HttpResponse.asString()).equals(RESPONSE);
+            resp = client.send(req, asString());
+            ok = resp.statusCode() == 200 && resp.body().equals(RESPONSE);
 
             if (!ok || ca.count != 1)
                 throw new RuntimeException("Test failed");
 
             // try a POST
 
-            req = client.request(uri)
-                    .body(HttpRequest.fromString(POST_BODY))
-                    .POST();
-            resp = req.response();
+            req = HttpRequest.newBuilder(uri)
+                             .POST(fromString(POST_BODY))
+                             .build();
+            resp = client.send(req, asString());
             ok = resp.statusCode() == 200;
 
             if (!ok || ca.count != 1)
                 throw new RuntimeException("Test failed");
         } finally {
-            client.executorService().shutdownNow();
             server.stop(0);
             e.shutdownNow();
         }
--- a/jdk/test/java/net/httpclient/BasicWebSocketAPITest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,328 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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.CharBuffer;
-import java.nio.channels.SocketChannel;
-import java.time.Duration;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.Consumer;
-
-/*
- * @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(null, true))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(IllegalArgumentException.class,
-                                ".*message.*",
-                                () -> ws.sendPing(ByteBuffer.allocate(126)))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(NullPointerException.class,
-                                "message",
-                                () -> ws.sendPing(null))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(IllegalArgumentException.class,
-                                ".*message.*",
-                                () -> ws.sendPong(ByteBuffer.allocate(126)))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(NullPointerException.class,
-                                "message",
-                                () -> ws.sendPong(null))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(NullPointerException.class,
-                                "message",
-                                () -> ws.sendText(null, true))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(NullPointerException.class,
-                                "message",
-                                () -> ws.sendText(null))
-        );
-        checkAndClose(
-                (ws) ->
-                        TestKit.assertThrows(IllegalArgumentException.class,
-                                "(?i).*reason.*",
-                                () -> ws.sendClose(CloseCode.NORMAL_CLOSURE, CharBuffer.allocate(124)))
-        );
-        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(Duration.ofSeconds(1))
-        );
-        // 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) { }
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/EchoHandler.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/EchoHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 
 import com.sun.net.httpserver.*;
 import java.net.*;
-import java.net.http.*;
+import jdk.incubator.http.*;
 import java.io.*;
 import java.util.concurrent.*;
 import javax.net.ssl.*;
@@ -33,8 +33,8 @@
 import java.util.List;
 import java.util.Random;
 import jdk.testlibrary.SimpleSSLContext;
-import static java.net.http.HttpRequest.*;
-import static java.net.http.HttpResponse.*;
+import static jdk.incubator.http.HttpRequest.*;
+import static jdk.incubator.http.HttpResponse.*;
 import java.util.logging.ConsoleHandler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
--- a/jdk/test/java/net/httpclient/HeadersTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/HeadersTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,7 +21,7 @@
  * questions.
  */
 
-import java.net.http.HttpRequest;
+import jdk.incubator.http.HttpRequest;
 import java.net.URI;
 
 /**
@@ -34,7 +34,7 @@
     static final URI TEST_URI = URI.create("http://www.foo.com/");
 
     static void bad(String name) {
-        HttpRequest.Builder builder = HttpRequest.create(TEST_URI);
+        HttpRequest.Builder builder = HttpRequest.newBuilder(TEST_URI);
         try {
             builder.header(name, "foo");
             throw new RuntimeException("Expected IAE for header:" + name);
@@ -42,7 +42,7 @@
     }
 
     static void good(String name) {
-        HttpRequest.Builder builder = HttpRequest.create(TEST_URI);
+        HttpRequest.Builder builder = HttpRequest.newBuilder(TEST_URI);
         try {
             builder.header(name, "foo");
         } catch (IllegalArgumentException e) {
--- a/jdk/test/java/net/httpclient/HeadersTest1.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/HeadersTest1.java	Tue Dec 13 02:04:23 2016 +0100
@@ -4,9 +4,7 @@
  *
  * This code is free software; you can redistribute 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.
+ * 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
@@ -26,83 +24,103 @@
 /*
  * @test
  * @bug 8153142
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          jdk.httpserver
- * @run main/othervm HeadersTest1
- * @summary HeadersTest1
+ * @run testng/othervm HeadersTest1
  */
 
-import com.sun.net.httpserver.HttpContext;
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-import com.sun.net.httpserver.HttpServer;
-import com.sun.net.httpserver.Headers;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpHeaders;
-import java.net.http.HttpResponse;
-import java.net.http.HttpRequest;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpHeaders;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.List;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import org.testng.annotations.Test;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 import static java.nio.charset.StandardCharsets.US_ASCII;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 
 public class HeadersTest1 {
 
-    final static String RESPONSE = "Hello world";
+    private static final String RESPONSE = "Hello world";
 
-    public static void main(String[] args) throws Exception {
+    @Test
+    public void test() throws Exception {
         HttpServer server = HttpServer.create(new InetSocketAddress(0), 10);
-        ExecutorService e = Executors.newCachedThreadPool();
         Handler h = new Handler();
-        HttpContext serverContext = server.createContext("/test", h);
+        server.createContext("/test", h);
         int port = server.getAddress().getPort();
         System.out.println("Server port = " + port);
 
+        ExecutorService e = Executors.newCachedThreadPool();
         server.setExecutor(e);
         server.start();
-        HttpClient client = HttpClient.create()
+        HttpClient client = HttpClient.newBuilder()
+                                      .executor(e)
                                       .build();
 
         try {
             URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/test/foo");
-            HttpRequest req = client.request(uri)
-                .headers("X-Bar", "foo1")
-                .headers("X-Bar", "foo2")
-                .GET();
+            HttpRequest req = HttpRequest.newBuilder(uri)
+                                         .headers("X-Bar", "foo1")
+                                         .headers("X-Bar", "foo2")
+                                         .GET()
+                                         .build();
 
-            HttpResponse resp = req.response();
-            if (resp.statusCode() != 200)
-                throw new RuntimeException("Test failed: status code");
+            HttpResponse<?> resp = client.send(req, asString());
+            if (resp.statusCode() != 200) {
+                throw new RuntimeException("Expected 200, got: " + resp.statusCode());
+            }
             HttpHeaders hd = resp.headers();
-            List<String> v = hd.allValues("X-Foo-Response");
-            if (!v.contains("resp1"))
-                throw new RuntimeException("Test failed: resp1");
-            if (!v.contains("resp2"))
-                throw new RuntimeException("Test failed: resp2");
+
+            assertTrue(!hd.firstValue("Non-Existent-Header").isPresent());
+
+            List<String> v1 = hd.allValues("Non-Existent-Header");
+            assertNotNull(v1);
+            assertTrue(v1.isEmpty(), String.valueOf(v1));
+            TestKit.assertUnmodifiableList(v1);
 
+            List<String> v2 = hd.allValues("X-Foo-Response");
+            assertNotNull(v2);
+            assertEquals(new HashSet<>(v2), Set.of("resp1", "resp2"));
+            TestKit.assertUnmodifiableList(v2);
+
+            Map<String, List<String>> map = hd.map();
+            TestKit.assertUnmodifiableMap(map);
+            for (List<String> values : map.values()) {
+                TestKit.assertUnmodifiableList(values);
+            }
         } finally {
-            client.executorService().shutdownNow();
             server.stop(0);
             e.shutdownNow();
         }
         System.out.println("OK");
     }
 
-   static class Handler implements HttpHandler {
+    private static final class Handler implements HttpHandler {
 
         @Override
         public void handle(HttpExchange he) throws IOException {
-            String method = he.getRequestMethod();
-            InputStream is = he.getRequestBody();
             List<String> l = he.getRequestHeaders().get("X-Bar");
             if (!l.contains("foo1") || !l.contains("foo2")) {
-                for (String s : l)
+                for (String s : l) {
                     System.out.println("HH: " + s);
+                }
                 he.sendResponseHeaders(500, -1);
                 he.close();
                 return;
@@ -115,6 +133,5 @@
             os.write(RESPONSE.getBytes(US_ASCII));
             os.close();
         }
-
-   }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/HttpInputStreamTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,333 @@
+/*
+ * 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.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpHeaders;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Flow;
+import java.util.stream.Stream;
+
+/*
+ * @test
+ * @summary An example on how to read a response body with InputStream...
+ * @run main/othervm HttpInputStreamTest
+ * @author daniel fuchs
+ */
+public class HttpInputStreamTest {
+
+    public static boolean DEBUG = Boolean.getBoolean("test.debug");
+
+    /**
+     * A simple HttpResponse.BodyHandler that creates a live
+     * InputStream to read the response body from the underlying ByteBuffer
+     * Flow.
+     * The InputStream is made immediately available for consumption, before
+     * the response body is fully received.
+     */
+    public static class HttpInputStreamHandler
+        implements HttpResponse.BodyHandler<InputStream>    {
+
+        public static final int MAX_BUFFERS_IN_QUEUE = 1;
+
+        private final int maxBuffers;
+
+        public HttpInputStreamHandler() {
+            this(MAX_BUFFERS_IN_QUEUE);
+        }
+
+        public HttpInputStreamHandler(int maxBuffers) {
+            this.maxBuffers = maxBuffers <= 0 ? MAX_BUFFERS_IN_QUEUE : maxBuffers;
+        }
+
+        @Override
+        public synchronized HttpResponse.BodyProcessor<InputStream>
+                apply(int i, HttpHeaders hh) {
+            return new HttpResponseInputStream(maxBuffers);
+        }
+
+        /**
+         * An InputStream built on top of the Flow API.
+         */
+        private static class HttpResponseInputStream extends InputStream
+                    implements HttpResponse.BodyProcessor<InputStream> {
+
+            // An immutable ByteBuffer sentinel to mark that the last byte was received.
+            private static final ByteBuffer LAST = ByteBuffer.wrap(new byte[0]);
+
+            // A queue of yet unprocessed ByteBuffers received from the flow API.
+            private final BlockingQueue<ByteBuffer> buffers;
+            private volatile Flow.Subscription subscription;
+            private volatile boolean closed;
+            private volatile Throwable failed;
+            private volatile ByteBuffer current;
+
+            HttpResponseInputStream() {
+                this(MAX_BUFFERS_IN_QUEUE);
+            }
+
+            HttpResponseInputStream(int maxBuffers) {
+                int capacity = maxBuffers <= 0 ? MAX_BUFFERS_IN_QUEUE : maxBuffers;
+                this.buffers = new ArrayBlockingQueue<>(capacity);
+            }
+
+            @Override
+            public CompletionStage<InputStream> getBody() {
+                // Return the stream immediately, before the
+                // response body is received.
+                // This makes it possible for senAsync().get().body()
+                // to complete before the response body is received.
+                return CompletableFuture.completedStage(this);
+            }
+
+            // Returns the current byte buffer to read from.
+            // If the current buffer has no remaining data, will take the
+            // next buffer from the buffers queue, possibly blocking until
+            // a new buffer is made available through the Flow API, or the
+            // end of the flow is reached.
+            private ByteBuffer current() throws IOException {
+                while (current == null || !current.hasRemaining()) {
+                    // Check whether the stream is claused or exhausted
+                    if (closed || failed != null) {
+                        throw new IOException("closed", failed);
+                    }
+                    if (current == LAST) break;
+
+                    try {
+                        // Take a new buffer from the queue, blocking
+                        // if none is available yet...
+                        if (DEBUG) System.err.println("Taking Buffer");
+                        current = buffers.take();
+                        if (DEBUG) System.err.println("Buffer Taken");
+
+                        // Check whether some exception was encountered
+                        // upstream
+                        if (closed || failed != null) {
+                            throw new IOException("closed", failed);
+                        }
+
+                        // Check whether we're done.
+                        if (current == LAST) break;
+
+                        // Inform the producer that it can start sending
+                        // us a new buffer
+                        Flow.Subscription s = subscription;
+                        if (s != null) s.request(1);
+
+                    } catch (InterruptedException ex) {
+                        // continue
+                    }
+                }
+                assert current == LAST || current.hasRemaining();
+                return current;
+            }
+
+            @Override
+            public int read(byte[] bytes, int off, int len) throws IOException {
+                // get the buffer to read from, possibly blocking if
+                // none is available
+                ByteBuffer buffer;
+                if ((buffer = current()) == LAST) return -1;
+
+                // don't attempt to read more than what is available
+                // in the current buffer.
+                int read = Math.min(buffer.remaining(), len);
+                assert read > 0 && read <= buffer.remaining();
+
+                // buffer.get() will do the boundary check for us.
+                buffer.get(bytes, off, read);
+                return read;
+            }
+
+            @Override
+            public int read() throws IOException {
+                ByteBuffer buffer;
+                if ((buffer = current()) == LAST) return -1;
+                return buffer.get() & 0xFF;
+            }
+
+            @Override
+            public void onSubscribe(Flow.Subscription s) {
+                this.subscription = s;
+                s.request(Math.max(2, buffers.remainingCapacity() + 1));
+            }
+
+            @Override
+            public synchronized void onNext(ByteBuffer t) {
+                try {
+                    if (DEBUG) System.err.println("next buffer received");
+                    buffers.put(t);
+                    if (DEBUG) System.err.println("buffered offered");
+                } catch (Exception ex) {
+                    failed = ex;
+                    try {
+                        close();
+                    } catch (IOException ex1) {
+                        // OK
+                    }
+                }
+            }
+
+            @Override
+            public void onError(Throwable thrwbl) {
+                failed = thrwbl;
+            }
+
+            @Override
+            public synchronized void onComplete() {
+                subscription = null;
+                onNext(LAST);
+            }
+
+            @Override
+            public void close() throws IOException {
+                synchronized (this) {
+                    closed = true;
+                    Flow.Subscription s = subscription;
+                    if (s != null) {
+                        s.cancel();
+                    }
+                    subscription = null;
+                }
+                super.close();
+            }
+
+        }
+    }
+
+    /**
+     * Examine the response headers to figure out the charset used to
+     * encode the body content.
+     * If the content type is not textual, returns an empty Optional.
+     * Otherwise, returns the body content's charset, defaulting to
+     * ISO-8859-1 if none is explicitly specified.
+     * @param headers The response headers.
+     * @return The charset to use for decoding the response body, if
+     *         the response body content is text/...
+     */
+    public static Optional<Charset> getCharset(HttpHeaders headers) {
+        Optional<String> contentType = headers.firstValue("Content-Type");
+        Optional<Charset> charset = Optional.empty();
+        if (contentType.isPresent()) {
+            final String[] values = contentType.get().split(";");
+            if (values[0].startsWith("text/")) {
+                charset = Optional.of(Stream.of(values)
+                    .map(x -> x.toLowerCase(Locale.ROOT))
+                    .map(String::trim)
+                    .filter(x -> x.startsWith("charset="))
+                    .map(x -> x.substring("charset=".length()))
+                    .findFirst()
+                    .orElse("ISO-8859-1"))
+                    .map(Charset::forName);
+            }
+        }
+        return charset;
+    }
+
+    public static void main(String[] args) throws Exception {
+        HttpClient client = HttpClient.newHttpClient();
+        HttpRequest request = HttpRequest
+            .newBuilder(new URI("http://hg.openjdk.java.net/jdk9/sandbox/jdk/shortlog/http-client-branch/"))
+            .GET()
+            .build();
+
+        // This example shows how to return an InputStream that can be used to
+        // start reading the response body before the response is fully received.
+        // In comparison, the snipet below (which uses
+        // HttpResponse.BodyHandler.asString()) obviously will not return before the
+        // response body is fully read:
+        //
+        // System.out.println(
+        //    client.sendAsync(request, HttpResponse.BodyHandler.asString()).get().body());
+
+        CompletableFuture<HttpResponse<InputStream>> handle =
+            client.sendAsync(request, new HttpInputStreamHandler());
+        if (DEBUG) System.err.println("Request sent");
+
+        HttpResponse<InputStream> pending = handle.get();
+
+        // At this point, the response headers have been received, but the
+        // response body may not have arrived yet. This comes from
+        // the implementation of HttpResponseInputStream::getBody above,
+        // which returns an already completed completion stage, without
+        // waiting for any data.
+        // We can therefore access the headers - and the body, which
+        // is our live InputStream, without waiting...
+        HttpHeaders responseHeaders = pending.headers();
+
+        // Get the charset declared in the response headers.
+        // The optional will be empty if the content type is not
+        // of type text/...
+        Optional<Charset> charset = getCharset(responseHeaders);
+
+        try (InputStream is = pending.body();
+            // We assume a textual content type. Construct an InputStream
+            // Reader with the appropriate Charset.
+            // charset.get() will throw NPE if the content is not textual.
+            Reader r = new InputStreamReader(is, charset.get())) {
+
+            char[] buff = new char[32];
+            int off=0, n=0;
+            if (DEBUG) System.err.println("Start receiving response body");
+            if (DEBUG) System.err.println("Charset: " + charset.get());
+
+            // Start consuming the InputStream as the data arrives.
+            // Will block until there is something to read...
+            while ((n = r.read(buff, off, buff.length - off)) > 0) {
+                assert (buff.length - off) > 0;
+                assert n <= (buff.length - off);
+                if (n == (buff.length - off)) {
+                    System.out.print(buff);
+                    off = 0;
+                } else {
+                    off += n;
+                }
+                assert off < buff.length;
+            }
+
+            // last call to read may not have filled 'buff' completely.
+            // flush out the remaining characters.
+            assert off >= 0 && off < buff.length;
+            for (int i=0; i < off; i++) {
+                System.out.print(buff[i]);
+            }
+
+            // We're done!
+            System.out.println("Done!");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/HttpRequestBuilderTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,183 @@
+/*
+ * 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 jdk.incubator.http.HttpRequest;
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import java.time.Duration;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @test
+ * @bug 8170064
+ * @summary  HttpRequest API documentation says:" Unless otherwise stated,
+ * {@code null} parameter values will cause methods
+ * of this class to throw {@code NullPointerException}".
+ */
+public class HttpRequestBuilderTest {
+
+    static final URI TEST_URI = URI.create("http://www.foo.com/");
+
+
+    public static void main(String[] args) throws Exception {
+
+        HttpRequest.Builder builder = HttpRequest.newBuilder();
+        builder = test1("uri", builder, builder::uri, (URI)null,
+                        NullPointerException.class);
+        builder = test2("header", builder, builder::header, (String) null, "bar",
+                        NullPointerException.class);
+        builder = test2("header", builder, builder::header, "foo", (String) null,
+                        NullPointerException.class);
+        builder = test2("header", builder, builder::header, (String)null,
+                        (String) null, NullPointerException.class);
+        builder = test1("headers", builder, builder::headers, (String[]) null,
+                        NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                        (String[]) new String[] {null, "bar"},
+                        NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                        (String[]) new String[] {"foo", null},
+                        NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                        (String[]) new String[] {null, null},
+                        NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                       (String[]) new String[] {"foo", "bar", null},
+                       NullPointerException.class,
+                       IllegalArgumentException.class);
+        builder = test1("headers", builder, builder::headers,
+                       (String[]) new String[] {"foo", "bar", null, null},
+                       NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                       (String[]) new String[] {"foo", "bar", "baz", null},
+                       NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                       (String[]) new String[] {"foo", "bar", null, "baz"},
+                       NullPointerException.class);
+        builder = test1("headers", builder, builder::headers,
+                       (String[]) new String[] {"foo", "bar", "baz"},
+                       IllegalArgumentException.class);
+        builder = test1("headers", builder, builder::headers,
+                       (String[]) new String[] {"foo"},
+                       IllegalArgumentException.class);
+        builder = test1("DELETE", builder, builder::DELETE,
+                        (HttpRequest.BodyProcessor)null, null);
+        builder = test1("POST", builder, builder::POST,
+                        (HttpRequest.BodyProcessor)null, null);
+        builder = test1("PUT", builder, builder::PUT,
+                        (HttpRequest.BodyProcessor)null, null);
+        builder = test2("method", builder, builder::method, "GET",
+                        (HttpRequest.BodyProcessor) null, null);
+        builder = test2("setHeader", builder, builder::setHeader,
+                        (String) null, "bar",
+                        NullPointerException.class);
+        builder = test2("setHeader", builder, builder::setHeader,
+                        "foo", (String) null,
+                        NullPointerException.class);
+        builder = test2("setHeader", builder, builder::setHeader,
+                        (String)null, (String) null,
+                        NullPointerException.class);
+        builder = test1("timeout", builder, builder::timeout,
+                        (Duration)null, NullPointerException.class);
+        builder = test1("version", builder, builder::version,
+                        (HttpClient.Version)null,
+                        NullPointerException.class);
+        builder = test2("method", builder, builder::method, null,
+                       HttpRequest.BodyProcessor.fromString("foo"),
+                       NullPointerException.class);
+// see JDK-8170093
+//
+//        builder = test2("method", builder, builder::method, "foo",
+//                       HttpRequest.BodyProcessor.fromString("foo"),
+//                       IllegalArgumentException.class);
+//
+//        builder.build();
+
+    }
+
+    private static boolean shouldFail(Class<? extends Exception> ...exceptions) {
+        return exceptions != null && exceptions.length > 0;
+    }
+
+    private static String expectedNames(Class<? extends Exception> ...exceptions) {
+        return Stream.of(exceptions).map(Class::getSimpleName)
+                .collect(Collectors.joining("|"));
+    }
+    private static boolean isExpected(Exception x,
+                                     Class<? extends Exception> ...expected) {
+        return expected != null && Stream.of(expected)
+                .filter(c -> c.isInstance(x))
+                .findAny().isPresent();
+    }
+
+    public static <R,P> R test1(String name, R receiver, Function<P, R> m, P arg,
+                               Class<? extends Exception> ...ex) {
+        try {
+            R result =  m.apply(arg);
+            if (!shouldFail(ex)) {
+                System.out.println("success: " + name + "(" + arg + ")");
+                return result;
+            } else {
+                throw new AssertionError("Expected " + expectedNames(ex)
+                    + " not raised for " + name + "(" + arg + ")");
+            }
+        } catch (Exception x) {
+            if (!isExpected(x, ex)) {
+                throw x;
+            } else {
+                System.out.println("success: " + name + "(" + arg + ")" +
+                        " - Got expected exception: " + x);
+                return receiver;
+            }
+        }
+    }
+
+
+    public static <R,P1, P2> R test2(String name, R receiver, BiFunction<P1, P2, R> m,
+                               P1 arg1, P2 arg2,
+                               Class<? extends Exception> ...ex) {
+        try {
+            R result =  m.apply(arg1, arg2);
+            if (!shouldFail(ex)) {
+                System.out.println("success: " + name + "(" + arg1 + ", "
+                                   + arg2 + ")");
+                return result;
+            } else {
+                throw new AssertionError("Expected " + expectedNames(ex)
+                    + " not raised for "
+                    + name + "(" + arg1 +", " + arg2 + ")");
+            }
+        } catch (Exception x) {
+            if (!isExpected(x, ex)) {
+                throw x;
+            } else {
+                System.out.println("success: " + name + "(" + arg1 + ", "
+                        + arg2 + ") - Got expected exception: " + x);
+                return receiver;
+            }
+        }
+    }
+}
--- a/jdk/test/java/net/httpclient/HttpUtils.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import static java.net.http.HttpRequest.fromByteArray;
-import static java.net.http.HttpRequest.fromByteArrays;
-import static java.net.http.HttpRequest.fromFile;
-import static java.net.http.HttpRequest.fromInputStream;
-import static java.net.http.HttpRequest.fromString;
-import java.net.http.HttpResponse;
-import static java.net.http.HttpResponse.asByteArray;
-import static java.net.http.HttpResponse.asFile;
-import static java.net.http.HttpResponse.asInputStream;
-import static java.net.http.HttpResponse.asString;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-
-public final class HttpUtils {
-
-    static final int DEFAULT_OFFSET = 10;
-    static final int DEFAULT_LENGTH = 1000;
-    static final String midSizedFilename = "/files/notsobigfile.txt";
-    static final String smallFilename = "/files/smallfile.txt";
-    static final Path midSizedFile;
-    static final Path smallFile;
-    static final String fileroot;
-
-    public enum RequestBody {
-        STRING, FILE, BYTE_ARRAY, BYTE_ARRAY_OFFSET, INPUTSTREAM, STRING_WITH_CHARSET,
-    }
-
-    static {
-        fileroot = System.getProperty("test.src") + "/docs";
-        midSizedFile = Paths.get(fileroot + midSizedFilename);
-        smallFile = Paths.get(fileroot + smallFilename);
-    }
-
-    static public String getFileContent(String path) throws IOException {
-        FileInputStream fis = new FileInputStream(path);
-        byte[] buf = new byte[2 * 1024];
-        StringBuilder sb = new StringBuilder();
-        int byteRead;
-        while ((byteRead = fis.read(buf)) != -1) {
-            sb.append(new String(buf, 0, byteRead, "US-ASCII"));
-        }
-        return sb.toString();
-    }
-
-    public static HttpRequest.Builder getHttpRequestBuilder(final HttpClient client,
-                                                            final String requestType,
-                                                            final URI uri)
-        throws IOException
-    {
-        HttpRequest.Builder builder;
-        String filename = smallFile.toFile().getAbsolutePath();
-        String fileContents = HttpUtils.getFileContent(filename);
-        byte buf[] = fileContents.getBytes();
-        switch (requestType) {
-            case "InputStream":
-                InputStream inputStream = new FileInputStream(smallFile.toFile());
-                builder = client.request(uri)
-                                .body(fromInputStream(inputStream));
-                break;
-            case "byteArray":
-                builder = client.request(uri)
-                                .body(fromByteArray(buf));
-                break;
-            case "byteArrays":
-                Iterable iterable = Arrays.asList(buf);
-                builder = client.request(uri)
-                                .body(fromByteArrays(iterable.iterator()));
-                break;
-            case "string":
-                builder = client.request(uri)
-                                .body(fromString(fileContents));
-                break;
-            case "byteArray_offset":
-                builder = client.request(uri)
-                                .body(fromByteArray(buf,
-                                                    DEFAULT_OFFSET,
-                                                    DEFAULT_LENGTH));
-                break;
-            case "file":
-                builder = client.request(uri)
-                                .body(fromFile(smallFile));
-                break;
-            case "string_charset":
-                builder = client.request(uri)
-                                .body(fromString(new String(buf),
-                                                 Charset.defaultCharset()));
-                break;
-            default:
-                builder = null;
-                break;
-        }
-        return builder;
-    }
-
-    public static void checkResponse(final HttpResponse response,
-                                     String requestType,
-                                     final String responseType)
-        throws IOException
-    {
-        String filename = smallFile.toFile().getAbsolutePath();
-        String fileContents = HttpUtils.getFileContent(filename);
-        if (requestType.equals("byteArray_offset")) {
-            fileContents = fileContents.substring(DEFAULT_OFFSET,
-                                                  DEFAULT_OFFSET + DEFAULT_LENGTH);
-        }
-        byte buf[] = fileContents.getBytes();
-        String responseBody;
-        switch (responseType) {
-            case "string":
-                responseBody = response.body(asString());
-                if (!responseBody.equals(fileContents)) {
-                    throw new RuntimeException();
-                }
-                break;
-            case "byteArray":
-                byte arr[] = response.body(asByteArray());
-                if (!Arrays.equals(arr, buf)) {
-                    throw new RuntimeException();
-                }
-                break;
-            case "file":
-                response.body(asFile(Paths.get("barf.txt")));
-                Path downloaded = Paths.get("barf.txt");
-                if (Files.size(downloaded) != fileContents.length()) {
-                    throw new RuntimeException("Size mismatch");
-                }
-                break;
-            case "InputStream":
-                InputStream is = response.body(asInputStream());
-                byte arr1[] = new byte[1024];
-                int byteRead;
-                StringBuilder sb = new StringBuilder();
-                while ((byteRead = is.read(arr1)) != -1) {
-                    sb.append(new String(arr1, 0, byteRead));
-                }
-                if (!sb.toString().equals(fileContents)) {
-                    throw new RuntimeException();
-                }
-                break;
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/ImmutableHeaders.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/ImmutableHeaders.java	Tue Dec 13 02:04:23 2016 +0100
@@ -4,9 +4,7 @@
  *
  * This code is free software; you can redistribute 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.
+ * 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
@@ -26,13 +24,12 @@
 /**
  * @test
  * @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          jdk.httpserver
  * @run main/othervm ImmutableHeaders
  * @summary ImmutableHeaders
  */
 
-import com.sun.net.httpserver.HttpContext;
 import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
@@ -41,13 +38,13 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
-import java.net.PasswordAuthentication;
 import java.net.URI;
-import java.net.http.*;
+import jdk.incubator.http.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.List;
 import static java.nio.charset.StandardCharsets.US_ASCII;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
 
 public class ImmutableHeaders {
 
@@ -55,23 +52,25 @@
 
     public static void main(String[] args) throws Exception {
         HttpServer server = HttpServer.create(new InetSocketAddress(0), 10);
-        ExecutorService e = Executors.newCachedThreadPool();
-        Handler h = new Handler();
-        HttpContext serverContext = server.createContext("/test", h);
+        ExecutorService serverExecutor = Executors.newCachedThreadPool();
+        ExecutorService clientExecutor = Executors.newCachedThreadPool();
+        server.createContext("/test", new ImmutableHeadersHandler());
         int port = server.getAddress().getPort();
         System.out.println("Server port = " + port);
 
-        server.setExecutor(e);
+        server.setExecutor(serverExecutor);
         server.start();
-        HttpClient client = HttpClient.create()
+        HttpClient client = HttpClient.newBuilder()
+                                      .executor(clientExecutor)
                                       .build();
 
         try {
-            URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/test/foo");
-            HttpRequest req = client.request(uri)
-                .headers("X-Foo", "bar")
-                .headers("X-Bar", "foo")
-                .GET();
+            URI uri = new URI("http://127.0.0.1:" + port + "/test/foo");
+            HttpRequest req = HttpRequest.newBuilder(uri)
+                                         .headers("X-Foo", "bar")
+                                         .headers("X-Bar", "foo")
+                                         .GET()
+                                         .build();
 
             try {
                 HttpHeaders hd = req.headers();
@@ -82,7 +81,7 @@
                 throw new RuntimeException("Test failed");
             } catch (UnsupportedOperationException ex) {
             }
-            HttpResponse resp = req.response();
+            HttpResponse resp = client.send(req, discard(null));
             try {
                 HttpHeaders hd = resp.headers();
                 List<String> v = hd.allValues("X-Foo-Response");
@@ -94,14 +93,14 @@
             }
 
         } finally {
-            client.executorService().shutdownNow();
+            clientExecutor.shutdownNow();
+            serverExecutor.shutdownNow();
             server.stop(0);
-            e.shutdownNow();
         }
         System.out.println("OK");
     }
 
-   static class Handler implements HttpHandler {
+   static class ImmutableHeadersHandler implements HttpHandler {
 
         @Override
         public void handle(HttpExchange he) throws IOException {
--- a/jdk/test/java/net/httpclient/ManyRequests.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/ManyRequests.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,38 +24,38 @@
 /*
  * @test
  * @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          java.logging
  *          jdk.httpserver
  * @library /lib/testlibrary/ /
  * @build jdk.testlibrary.SimpleSSLContext EchoHandler
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
- * @run main/othervm/timeout=40 -Djava.net.http.HttpClient.log=ssl ManyRequests
+ * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests
  * @summary Send a large number of requests asynchronously
  */
 
-//package javaapplication16;
-
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsParameters;
 import com.sun.net.httpserver.HttpsServer;
 import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
 import java.net.InetSocketAddress;
 import java.net.URI;
 import java.util.Arrays;
+import java.util.Formatter;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Random;
+import java.util.concurrent.ExecutorService;
 import java.util.logging.Logger;
 import java.util.logging.Level;
 import java.util.concurrent.CompletableFuture;
 import javax.net.ssl.SSLContext;
 import jdk.testlibrary.SimpleSSLContext;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromByteArray;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asByteArray;
 
 public class ManyRequests {
 
@@ -72,7 +72,7 @@
         HttpsServer server = HttpsServer.create(addr, 0);
         server.setHttpsConfigurator(new Configurator(ctx));
 
-        HttpClient client = HttpClient.create()
+        HttpClient client = HttpClient.newBuilder()
                                       .sslContext(ctx)
                                       .build();
         try {
@@ -80,7 +80,7 @@
             System.out.println("OK");
         } finally {
             server.stop(0);
-            client.executorService().shutdownNow();
+            ((ExecutorService)client.executor()).shutdownNow();
         }
     }
 
@@ -95,55 +95,64 @@
 
         RequestLimiter limiter = new RequestLimiter(40);
         Random rand = new Random();
-        CompletableFuture<Void>[] results = new CompletableFuture[REQUESTS];
+        CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS];
         HashMap<HttpRequest,byte[]> bodies = new HashMap<>();
 
         for (int i=0; i<REQUESTS; i++) {
             byte[] buf = new byte[i+1];  // different size bodies
             rand.nextBytes(buf);
-            HttpRequest r = client.request(uri)
-                                  .body(HttpRequest.fromByteArray(buf))
-                                  .POST();
+            HttpRequest r = HttpRequest.newBuilder(uri)
+                                       .POST(fromByteArray(buf))
+                                       .build();
             bodies.put(r, buf);
 
             results[i] =
                 limiter.whenOkToSend()
-                       .thenCompose((v) -> r.responseAsync())
+                       .thenCompose((v) -> client.sendAsync(r, asByteArray()))
                        .thenCompose((resp) -> {
                            limiter.requestComplete();
                            if (resp.statusCode() != 200) {
-                               resp.bodyAsync(HttpResponse.ignoreBody());
                                String s = "Expected 200, got: " + resp.statusCode();
                                return completedWithIOException(s);
                            } else {
                                counter++;
                                System.out.println("Result from " + counter);
                            }
-                           return resp.bodyAsync(HttpResponse.asByteArray())
+                           return CompletableFuture.completedStage(resp.body())
                                       .thenApply((b) -> new Pair<>(resp, b));
                        })
                       .thenAccept((pair) -> {
                           HttpRequest request = pair.t.request();
                           byte[] requestBody = bodies.get(request);
                           check(Arrays.equals(requestBody, pair.u),
-                                "bodies not equal");
+                                "bodies not equal:[" + bytesToHexString(requestBody)
+                                + "] [" + bytesToHexString(pair.u) + "]");
 
                       });
         }
 
         // wait for them all to complete and throw exception in case of error
-        //try {
-            CompletableFuture.allOf(results).join();
-        //} catch (Exception  e) {
-            //e.printStackTrace();
-            //throw e;
-        //}
+        CompletableFuture.allOf(results).join();
     }
 
     static <T> CompletableFuture<T> completedWithIOException(String message) {
         return CompletableFuture.failedFuture(new IOException(message));
     }
 
+    static String bytesToHexString(byte[] bytes) {
+        if (bytes == null)
+            return "null";
+
+        StringBuilder sb = new StringBuilder(bytes.length * 2);
+
+        Formatter formatter = new Formatter(sb);
+        for (byte b : bytes) {
+            formatter.format("%02x", b);
+        }
+
+        return sb.toString();
+    }
+
     static final class Pair<T,U> {
         Pair(T t, U u) {
             this.t = t; this.u = u;
@@ -211,15 +220,14 @@
             sb.append(o);
         throw new RuntimeException(sb.toString());
     }
-}
 
-class Configurator extends HttpsConfigurator {
-    public Configurator(SSLContext ctx) {
-        super(ctx);
-    }
+    static class Configurator extends HttpsConfigurator {
+        public Configurator(SSLContext ctx) {
+            super(ctx);
+        }
 
-    public void configure (HttpsParameters params) {
-        params.setSSLParameters (getSSLContext().getSupportedSSLParameters());
+        public void configure(HttpsParameters params) {
+            params.setSSLParameters(getSSLContext().getSupportedSSLParameters());
+        }
     }
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/MessageHeadersTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,175 @@
+/*
+ * 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 8164704
+ * @modules jdk.incubator.httpclient
+ *          jdk.httpserver
+ *          java.base/sun.net.www
+ * @run main MessageHeadersTest
+ * @summary Tests expected behavior of MessageHeader. This test
+ *          cannot be used to verify 8164704 - it simply verifies
+ *          the assumptions on which the fix is based.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+
+public class MessageHeadersTest {
+
+    static final String BODY =
+          "This is the body dude,\r\n"
+        + "not a header!\r\n";
+
+    static final String MESSAGE_OK =
+          "HTTP/1.1 200 OK\r\n"
+        + "Content-Length: " + BODY.length() + "\r\n"
+        + "MY-Folding-Header: YES\r\n"
+        + " OR\r\n"
+        + " NO\r\n"
+        + "\r\n"
+        + BODY;
+
+    static final String MESSAGE_NOK =
+          "HTTP/1.1 101 Switching Protocols\r\n"
+        + "\r\n";
+
+    static final class ByteBufferInputStream extends InputStream {
+        final ByteBuffer buffer;
+        int lastRead = -1;
+        ByteBufferInputStream(ByteBuffer buffer) {
+            this.buffer = buffer;
+        }
+        @Override
+        public int read() throws IOException {
+            if (buffer.hasRemaining()) {
+                return lastRead = buffer.get();
+            }
+            return -1;
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        testMessageHeaders(MESSAGE_OK);
+        testMessageHeaders(MESSAGE_NOK);
+    }
+
+    /**
+     * Verifies that MessageHeader behave as we expect.
+     * @param msg The response string.
+     * @throws IOException should not happen.
+     */
+    static void testMessageHeaders(String msg) throws IOException {
+        byte[] bytes = msg.getBytes("US-ASCII");
+        ByteBuffer buffer = ByteBuffer.wrap(bytes);
+
+        // Read status line
+        String statusLine = readStatusLine(buffer);
+        System.out.println("StatusLine: " + statusLine);
+        if (!statusLine.startsWith("HTTP/1.1")) {
+            throw new AssertionError("bad status line: " + statusLine);
+        }
+
+        // Wrap the buffer into an input stream and pass
+        // that to MessageHeader to read the header.
+        // We have two cases:
+        //    - MESSAGE_OK: there will be some headers to read,
+        //    - MESSAGE_NOK: there will be no headers to read.
+        ByteBufferInputStream bbis = new ByteBufferInputStream(buffer);
+        sun.net.www.MessageHeader mh = new sun.net.www.MessageHeader(bbis);
+
+        // Now get the expected length of the body
+        String contentLengthValue = mh.findValue("Content-length");
+        int contentLength = contentLengthValue == null ? 0
+            : Integer.parseInt(contentLengthValue);
+
+        // We again have two cases:
+        //    - MESSAGE_OK:  there should be a Content-length: header
+        //    - MESSAGE_NOK: there should be no Content-length: header
+        if (contentLengthValue == null) {
+            // MESSAGE_NOK has no headers and no body and therefore
+            // no Content-length: header.
+            if (!MESSAGE_NOK.equals(msg)) {
+                throw new AssertionError("Content-length: header not found");
+            }
+            // In that case we expect MessageHeader to read the CR but
+            // leave the LF in the buffer. We therefore need to consume
+            // the the LF in order to get an empty (all consumed) buffer.
+            // This is what ResponseHeaders does.
+            byte c = buffer.get();
+            if (c != '\n' || bbis.lastRead != '\r') {
+                throw new AssertionError("Unexpected byte sequence for empty body"
+                        + ": " + bbis.lastRead + " " + c + " expected "
+                        + (byte)'\r' + " " + (byte)'\n');
+            }
+        } else {
+            if (MESSAGE_NOK.equals(msg)) {
+                throw new AssertionError("Content-length: header found in"
+                          + " error 101 message");
+            }
+        }
+
+        // Now read the remaining bytes. It should either be
+        // the empty string (MESSAGE_NOK) or BODY (MESSAGE_OK),
+        // and it should not contains any leading CR or LF"
+        String remaining = readRemainingBytes(buffer);
+        System.out.println("Body: <<<" + remaining + ">>>");
+        if (remaining.length() != contentLength) {
+            throw new AssertionError("Unexpected body length: " + remaining.length()
+                     + " expected " + contentLengthValue);
+        }
+        if (contentLengthValue != null) {
+            if (!BODY.equals(remaining)) {
+                throw new AssertionError("Body does not match!");
+            }
+        }
+    }
+
+    static String readRemainingBytes(ByteBuffer buffer) throws UnsupportedEncodingException {
+        byte[] res = new byte[buffer.limit() - buffer.position()];
+        System.arraycopy(buffer.array(), buffer.position(), res, 0, res.length);
+        buffer.position(buffer.limit());
+        return new String(res, "US-ASCII");
+    }
+
+    static String readStatusLine(ByteBuffer buffer) throws IOException {
+        buffer.mark();
+        int p = buffer.position();
+        while(buffer.hasRemaining()) {
+            char c = (char)buffer.get();
+            if (c == '\r') {
+                c = (char)buffer.get();
+                if (c == '\n') {
+                    byte[] res = new byte[buffer.position() - p -2];
+                    System.arraycopy(buffer.array(), p, res, 0, res.length);
+                    return new String(res, "US-ASCII");
+                }
+            }
+        }
+        throw new IOException("Status line not found");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/MultiAuthTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,273 @@
+/*
+ * 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
+ * @modules jdk.incubator.httpclient
+ *          jdk.httpserver
+ * @run main/othervm MultiAuthTest
+ * @summary Basic Authentication test with multiple clients issuing
+ *          multiple requests. Includes password changes
+ *          on server and client side.
+ */
+
+import com.sun.net.httpserver.BasicAuthenticator;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.URI;
+import jdk.incubator.http.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+
+public class MultiAuthTest {
+
+    static volatile boolean ok;
+    static final String RESPONSE = "Hello world";
+    static final String POST_BODY = "This is the POST body " + UUID.randomUUID();
+
+    static HttpServer createServer(ExecutorService e, BasicAuthenticator sa) throws Exception {
+        HttpServer server = HttpServer.create(new InetSocketAddress(0), 10);
+        Handler h = new Handler();
+        HttpContext serverContext = server.createContext("/test", h);
+        serverContext.setAuthenticator(sa);
+        server.setExecutor(e);
+        server.start();
+        return server;
+    }
+
+    public interface HttpRequestBuilderFactory extends Function<URI, HttpRequest.Builder> {
+
+        default HttpRequest.Builder request(URI uri) {
+            return this.apply(uri);
+        }
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        ExecutorService e = Executors.newCachedThreadPool();
+        ServerAuth sa = new ServerAuth("foo realm");
+        HttpServer server = createServer(e, sa);
+        int port = server.getAddress().getPort();
+        System.out.println("Server port = " + port);
+
+        ClientAuth ca = new ClientAuth();
+        HttpClient client1 = HttpClient.newBuilder()
+                                       .authenticator(ca)
+                                       .build();
+        HttpClient client2 = HttpClient.newBuilder()
+                                       .authenticator(ca)
+                                       .build();
+        HttpClient client3 = HttpClient.newHttpClient();
+
+        try {
+            URI uri = new URI("http://127.0.0.1:" + port + "/test/foo");
+            System.out.println("URI: " + uri);
+
+            System.out.println("\nTesting with client #1, Authenticator #1");
+            test(client1, ca, uri, 1, null);
+            System.out.println("Testing again with client #1, Authenticator #1");
+            test(client1, ca, uri, 1, null);
+            System.out.println("Testing with client #2, Authenticator #1");
+            test(client2, ca, uri, 2, null);
+
+            System.out.println("Testing with default client"
+                               + " (HttpClient.newHttpClient()), no authenticator");
+            test(HttpClient.newHttpClient(), ca, uri, 2, IOException.class);
+
+            System.out.println("\nSetting default authenticator\n");
+            java.net.Authenticator.setDefault(ca);
+
+            System.out.println("Testing default client"
+                               + " (HttpClient.newHttpClient()), no authenticator");
+            test(HttpClient.newHttpClient(), ca, uri, 3, IOException.class);
+
+            System.out.println("Testing with client #4, no authenticator");
+            test(client3, ca, uri, 4, IOException.class);
+
+            String oldpwd = sa.passwd;
+            sa.passwd = "changed";
+            System.out.println("\nChanged server password\n");
+
+            sa.passwd = "changed";
+            System.out.println("\nChanged server password\n");
+
+            System.out.println("Testing with client #1, Authenticator #1"
+                                + " (count=" + ca.count.get() +")");
+            test(client1, ca, uri, 7, IOException.class);
+            System.out.println("Testing again with client #1, Authenticator #1"
+                                + " (count=" + ca.count.get() +")");
+            test(client1, ca, uri, 10, IOException.class);
+            System.out.println("Testing with client #2, Authenticator #1"
+                                + " (count=" + ca.count.get() +")");
+            test(client2, ca, uri, 14, IOException.class);
+
+            System.out.println("\nRestored server password"
+                                + " (count=" + ca.count.get() +")\n");
+            sa.passwd = oldpwd;
+
+            int count = ca.count.get(); // depends on retry limit...
+            System.out.println("Testing with client #1, Authenticator #1");
+            test(client1, ca, uri, count+1, null);
+            System.out.println("Testing again with client #1, Authenticator #1");
+            test(client1, ca, uri, count+1, null);
+            System.out.println("Testing with client #2, Authenticator #1");
+            test(client2, ca, uri, count+2, null);
+
+            sa.passwd = ca.passwd = "changed#2";
+            System.out.println("\nChanged password on both sides\n");
+
+            System.out.println("Testing with client #1, Authenticator #1");
+            test(client1, ca, uri, count+3, null);
+            System.out.println("Testing again with client #1, Authenticator #1");
+            test(client1, ca, uri, count+3, null);
+            System.out.println("Testing with client #2, Authenticator #1");
+            test(client2, ca, uri, count+4, null);
+        } finally {
+            server.stop(0);
+            e.shutdownNow();
+        }
+        System.out.println("OK");
+    }
+
+    static void test(HttpClient client,
+                     ClientAuth ca,
+                     URI uri,
+                     int expectCount,
+                     Class<? extends Exception> expectFailure)
+        throws IOException, InterruptedException
+    {
+        HttpRequest req = HttpRequest.newBuilder(uri).GET().build();
+
+        HttpResponse resp;
+        try {
+            resp = client.send(req, asString());
+            ok = resp.statusCode() == 200 &&
+                resp.body().equals(RESPONSE);
+            if (expectFailure != null) {
+                throw new RuntimeException("Expected " + expectFailure.getName()
+                         +" not raised");
+            }
+        } catch (IOException io) {
+            if (expectFailure != null) {
+                if (expectFailure.isInstance(io)) {
+                    System.out.println("Got expected exception: " + io);
+                    return;
+                }
+            }
+            throw io;
+        }
+
+        if (!ok || ca.count.get() != expectCount)
+            throw new RuntimeException("Test failed: ok=" + ok
+                 + " count=" + ca.count.get() + " (expected=" + expectCount+")");
+
+        // repeat same request, should succeed but no additional authenticator calls
+        resp = client.send(req, asString());
+        ok = resp.statusCode() == 200 &&
+                resp.body().equals(RESPONSE);
+
+        if (!ok || ca.count.get() != expectCount)
+            throw new RuntimeException("Test failed: ok=" + ok
+                 + " count=" + ca.count.get() + " (expected=" + expectCount+")");
+
+        // try a POST
+        req = HttpRequest.newBuilder(uri)
+                         .POST(fromString(POST_BODY))
+                         .build();
+        resp = client.send(req, asString());
+        ok = resp.statusCode() == 200;
+
+        if (!ok || ca.count.get() != expectCount)
+            throw new RuntimeException("Test failed");
+
+    }
+
+    static class ServerAuth extends BasicAuthenticator {
+
+        volatile String passwd = "passwd";
+
+        ServerAuth(String realm) {
+            super(realm);
+        }
+
+        @Override
+        public boolean checkCredentials(String username, String password) {
+            if (!"user".equals(username) || !passwd.equals(password)) {
+                return false;
+            }
+            return true;
+        }
+
+    }
+
+    static class ClientAuth extends java.net.Authenticator {
+        final AtomicInteger count = new AtomicInteger();
+        volatile String passwd = "passwd";
+
+        @Override
+        protected PasswordAuthentication getPasswordAuthentication() {
+            count.incrementAndGet();
+            return new PasswordAuthentication("user", passwd.toCharArray());
+        }
+    }
+
+   static class Handler implements HttpHandler {
+        static volatile boolean ok;
+
+        @Override
+        public void handle(HttpExchange he) throws IOException {
+            String method = he.getRequestMethod();
+            InputStream is = he.getRequestBody();
+            if (method.equalsIgnoreCase("POST")) {
+                String requestBody = new String(is.readAllBytes(), US_ASCII);
+                if (!requestBody.equals(POST_BODY)) {
+                    he.sendResponseHeaders(500, -1);
+                    ok = false;
+                } else {
+                    he.sendResponseHeaders(200, -1);
+                    ok = true;
+                }
+            } else { // GET
+                he.sendResponseHeaders(200, RESPONSE.length());
+                OutputStream os = he.getResponseBody();
+                os.write(RESPONSE.getBytes(US_ASCII));
+                os.close();
+                ok = true;
+            }
+        }
+
+   }
+}
--- a/jdk/test/java/net/httpclient/ProxyAuthTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/ProxyAuthTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -26,7 +26,7 @@
  * @test
  * @bug 8163561
  * @modules java.base/sun.net.www
- *          java.httpclient
+ *          jdk.incubator.httpclient
  * @summary Verify that Proxy-Authenticate header is correctly handled
  *
  * @run main/othervm ProxyAuthTest
@@ -45,11 +45,12 @@
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
 import java.util.Base64;
-
 import sun.net.www.MessageHeader;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
 
 public class ProxyAuthTest {
     private static final String AUTH_USER = "user";
@@ -66,14 +67,12 @@
             InetSocketAddress paddr = new InetSocketAddress("localhost", port);
 
             URI uri = new URI("http://www.google.ie/");
-            HttpClient client = HttpClient.create()
-                    .proxy(ProxySelector.of(paddr))
-                    .authenticator(auth)
-                    .build();
-            HttpResponse resp = client.request(uri)
-                    .GET()
-                    .responseAsync()
-                    .get();
+            HttpClient client = HttpClient.newBuilder()
+                                          .proxy(ProxySelector.of(paddr))
+                                          .authenticator(auth)
+                                          .build();
+            HttpRequest req = HttpRequest.newBuilder(uri).GET().build();
+            HttpResponse<?> resp = client.sendAsync(req, discard(null)).get();
             if (resp.statusCode() != 404) {
                 throw new RuntimeException("Unexpected status code: " + resp.statusCode());
             }
@@ -121,8 +120,7 @@
                     MessageHeader headers = new MessageHeader(in);
                     System.out.println("Proxy: received " + headers);
 
-                    String authInfo = headers
-                            .findValue("Proxy-Authorization");
+                    String authInfo = headers.findValue("Proxy-Authorization");
                     if (authInfo != null) {
                         authenticate(authInfo);
                         out.print("HTTP/1.1 404 Not found\r\n");
@@ -172,4 +170,3 @@
     }
 
 }
-
--- a/jdk/test/java/net/httpclient/QuickResponses.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.net.URI;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * @test
- * @bug 8087112
- * @build Server
- * @run main/othervm -Djava.net.HttpClient.log=all QuickResponses
- */
-
-/**
- * Tests the buffering of data on connections across multiple
- * responses
- */
-public class QuickResponses {
-
-    static Server server;
-
-    static String response(String body) {
-        return "HTTP/1.1 200 OK\r\nContent-length: " + Integer.toString(body.length())
-                + "\r\n\r\n" + body;
-    }
-
-    static final String responses[] = {
-        "Lorem ipsum",
-        "dolor sit amet",
-        "consectetur adipiscing elit, sed do eiusmod tempor",
-        "quis nostrud exercitation ullamco",
-        "laboris nisi",
-        "ut",
-        "aliquip ex ea commodo consequat." +
-        "Duis aute irure dolor in reprehenderit in voluptate velit esse" +
-        "cillum dolore eu fugiat nulla pariatur.",
-        "Excepteur sint occaecat cupidatat non proident."
-    };
-
-    static String entireResponse() {
-        String s = "";
-        for (String r : responses) {
-            s += response(r);
-        }
-        return s;
-    }
-
-    public static void main(String[] args) throws Exception {
-        server = new Server(0);
-        URI uri = new URI(server.getURL());
-        server.start();
-
-        HttpRequest request = HttpRequest.create(uri)
-                .GET();
-
-        CompletableFuture<HttpResponse> cf1 = request.responseAsync();
-        Server.Connection s1 = server.activity();
-        s1.send(entireResponse());
-
-        HttpResponse r = cf1.join();
-        if (r.statusCode()!= 200 || !r.body(HttpResponse.asString()).equals(responses[0]))
-            throw new RuntimeException("Failed on first response");
-
-        //now get the same identical response, synchronously to ensure same connection
-        int remaining = responses.length - 1;
-
-        for (int i=0; i<remaining; i++) {
-            r = HttpRequest.create(uri)
-                    .GET()
-                    .response();
-            if (r.statusCode()!= 200)
-                throw new RuntimeException("Failed");
-
-            String body = r.body(HttpResponse.asString());
-            if (!body.equals(responses[i+1]))
-                throw new RuntimeException("Failed");
-        }
-        HttpClient.getDefault().executorService().shutdownNow();
-        System.out.println("OK");
-    }
-}
--- a/jdk/test/java/net/httpclient/RequestBodyTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/RequestBodyTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,151 +23,280 @@
 
 /*
  * @test @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          java.logging
  *          jdk.httpserver
- * @library /lib/testlibrary/ /
+ * @library /lib/testlibrary/
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
  * @build LightWeightHttpServer
- * @build jdk.testlibrary.SimpleSSLContext ProxyServer
- * @run main/othervm RequestBodyTest
+ * @build jdk.testlibrary.SimpleSSLContext
+ * @run testng/othervm RequestBodyTest
  */
 
-import java.io.IOException;
+import java.io.*;
 import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.function.Supplier;
 import javax.net.ssl.SSLContext;
+import jdk.testlibrary.FileUtils;
+import static java.nio.charset.StandardCharsets.*;
+import static java.nio.file.StandardOpenOption.*;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.*;
+import static jdk.incubator.http.HttpResponse.BodyHandler.*;
+
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
 
 public class RequestBodyTest {
 
-    final static String STRING = "string";
-    final static String BYTE_ARRAY = "byteArray";
-    final static String BYTE_ARRAYS = "byteArrays";
-    final static String BYTE_ARRAY_OFFSET = "byteArray_offset";
-    final static String FILE = "file";
-    final static String STRING_CHARSET = "string_charset";
-    final static String INPUTSTREAM = "InputStream";
+    static final String fileroot = System.getProperty("test.src") + "/docs";
+    static final String midSizedFilename = "/files/notsobigfile.txt";
+    static final String smallFilename = "/files/smallfile.txt";
 
-    final static String midSizedFilename = "/files/notsobigfile.txt";
-    final static String smallFilename = "/files/smallfile.txt";
-    static Path midSizedFile;
-    static Path smallFile;
-    static String fileroot;
-    static HttpClient client;
-    static SSLContext ctx;
-    static String httproot;
-    static String httpsroot;
+    HttpClient client;
+    ExecutorService exec = Executors.newCachedThreadPool();
+    String httpURI;
+    String httpsURI;
 
-    public static void main(String args[]) throws Exception {
-        fileroot = System.getProperty("test.src") + "/docs";
-        midSizedFile = Paths.get(fileroot + midSizedFilename);
-        smallFile = Paths.get(fileroot + smallFilename);
-        //start the server
-        LightWeightHttpServer.initServer();
+    enum RequestBody {
+        BYTE_ARRAY,
+        BYTE_ARRAY_OFFSET,
+        BYTE_ARRAYS,
+        FILE,
+        INPUTSTREAM,
+        STRING,
+        STRING_WITH_CHARSET
+    }
 
-        httproot = LightWeightHttpServer.httproot;
-        httpsroot = LightWeightHttpServer.httpsroot;
-        ctx = LightWeightHttpServer.ctx;
-        client = HttpClient.create().sslContext(ctx)
-                .followRedirects(HttpClient.Redirect.ALWAYS)
-                .executorService(Executors.newCachedThreadPool())
-                .build();
+    enum ResponseBody {
+        BYTE_ARRAY,
+        BYTE_ARRAY_CONSUMER,
+        DISCARD,
+        FILE,
+        FILE_WITH_OPTION,
+        STRING,
+        STRING_WITH_CHARSET,
+    }
 
-        String TARGET = httproot + "echo/foo";
-        boolean isSync = false;
-        requestBodyTypes(TARGET, STRING, STRING, isSync);
-        requestBodyTypes(TARGET, STRING, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, STRING, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, STRING, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, STRING, FILE, isSync);
-
-        requestBodyTypes(TARGET, BYTE_ARRAY, STRING, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, FILE, isSync);
+    @BeforeTest
+    public void setup() throws Exception {
+        LightWeightHttpServer.initServer();
+        httpURI = LightWeightHttpServer.httproot + "echo/foo";
+        httpsURI = LightWeightHttpServer.httpsroot + "echo/foo";
 
-        requestBodyTypes(TARGET, BYTE_ARRAYS, STRING, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, FILE, isSync);
-
-        requestBodyTypes(TARGET, INPUTSTREAM, STRING, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, FILE, isSync);
+        SSLContext ctx = LightWeightHttpServer.ctx;
+        client = HttpClient.newBuilder()
+                           .sslContext(ctx)
+                           .followRedirects(HttpClient.Redirect.ALWAYS)
+                           .executor(exec)
+                           .build();
+    }
 
-        requestBodyTypes(TARGET, FILE, STRING, isSync);
-        requestBodyTypes(TARGET, FILE, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, FILE, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, FILE, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, FILE, FILE, isSync);
+    @AfterTest
+    public void teardown() throws Exception {
+        exec.shutdownNow();
+        LightWeightHttpServer.stop();
+    }
 
-        isSync = true;
-        requestBodyTypes(TARGET, STRING, STRING, isSync);
-        requestBodyTypes(TARGET, STRING, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, STRING, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, STRING, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, STRING, FILE, isSync);
+    @DataProvider
+    public Object[][] exchanges() throws Exception {
+        List<Object[]> values = new ArrayList<>();
 
-        requestBodyTypes(TARGET, BYTE_ARRAY, STRING, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAY, FILE, isSync);
+        for (boolean async : new boolean[] { false, true })
+            for (String uri : new String[] { httpURI, httpsURI })
+                for (String file : new String[] { smallFilename, midSizedFilename })
+                    for (RequestBody requestBodyType : RequestBody.values())
+                        for (ResponseBody responseBodyType : ResponseBody.values())
+                            values.add(new Object[]
+                                {uri, requestBodyType, responseBodyType, file, async});
 
-        requestBodyTypes(TARGET, BYTE_ARRAYS, STRING, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, BYTE_ARRAYS, FILE, isSync);
+        return values.stream().toArray(Object[][]::new);
+    }
 
-        requestBodyTypes(TARGET, INPUTSTREAM, STRING, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, INPUTSTREAM, FILE, isSync);
+    @Test(dataProvider = "exchanges")
+    void exchange(String target,
+                  RequestBody requestBodyType,
+                  ResponseBody responseBodyType,
+                  String file,
+                  boolean async)
+        throws Exception
+    {
+        Path filePath = Paths.get(fileroot + file);
+        URI uri = new URI(target);
 
-        requestBodyTypes(TARGET, FILE, STRING, isSync);
-        requestBodyTypes(TARGET, FILE, BYTE_ARRAY, isSync);
-        requestBodyTypes(TARGET, FILE, BYTE_ARRAYS, isSync);
-        requestBodyTypes(TARGET, FILE, INPUTSTREAM, isSync);
-        requestBodyTypes(TARGET, FILE, FILE, isSync);
+        HttpRequest request = createRequest(uri, requestBodyType, filePath);
 
+        checkResponse(client, request, requestBodyType, responseBodyType, filePath, async);
     }
 
-    static void requestBodyTypes(final String target,
-                                 final String requestType,
-                                 final String responseType,
-                                 final boolean isAsync)
-        throws Exception
+    static final int DEFAULT_OFFSET = 10;
+    static final int DEFAULT_LENGTH = 1000;
+
+    HttpRequest createRequest(URI uri,
+                              RequestBody requestBodyType,
+                              Path file)
+        throws IOException
+    {
+        HttpRequest.Builder rb =  HttpRequest.newBuilder(uri);
+
+        String filename = file.toFile().getAbsolutePath();
+        byte[] fileAsBytes = getFileBytes(filename);
+        String fileAsString = new String(fileAsBytes, UTF_8);
+
+        switch (requestBodyType) {
+            case BYTE_ARRAY:
+                rb.POST(fromByteArray(fileAsBytes));
+                break;
+            case BYTE_ARRAY_OFFSET:
+                rb.POST(fromByteArray(fileAsBytes, DEFAULT_OFFSET, DEFAULT_LENGTH));
+                break;
+            case BYTE_ARRAYS:
+                Iterable<byte[]> iterable = Arrays.asList(fileAsBytes);
+                rb.POST(fromByteArrays(iterable));
+                break;
+            case FILE:
+                rb.POST(fromFile(file));
+                break;
+            case INPUTSTREAM:
+                rb.POST(fromInputStream(fileInputStreamSupplier(file)));
+                break;
+            case STRING:
+                rb.POST(fromString(fileAsString));
+                break;
+            case STRING_WITH_CHARSET:
+                rb.POST(fromString(new String(fileAsBytes), Charset.defaultCharset()));
+                break;
+            default:
+                throw new AssertionError("Unknown request body:" + requestBodyType);
+        }
+        return rb.build();
+    }
+
+    void checkResponse(HttpClient client,
+                       HttpRequest request,
+                       RequestBody requestBodyType,
+                       ResponseBody responseBodyType,
+                       Path file,
+                       boolean async)
+        throws InterruptedException, IOException
     {
-        System.out.println("Running test_request_body_type " + requestType +
-                " and response type " + responseType + " and sync=" + isAsync);
-        URI uri = new URI(target);
-        byte buf[];
-        String filename = smallFile.toFile().getAbsolutePath();
-        String fileContents = HttpUtils.getFileContent(filename);
-        buf = fileContents.getBytes();
-        HttpRequest.Builder builder = HttpUtils.getHttpRequestBuilder(client,
-                                                                      requestType,
-                                                                      uri);
-        HttpResponse response;
-        if (!isAsync) {
-            response = builder.GET().response();
-        } else {
-            response = builder.GET().responseAsync().join();
+        String filename = file.toFile().getAbsolutePath();
+        byte[] fileAsBytes = getFileBytes(filename);
+        if (requestBodyType == RequestBody.BYTE_ARRAY_OFFSET) {
+            // Truncate the expected response body, if only a portion was sent
+            fileAsBytes = Arrays.copyOfRange(fileAsBytes,
+                                             DEFAULT_OFFSET,
+                                             DEFAULT_OFFSET + DEFAULT_LENGTH);
         }
-        HttpUtils.checkResponse(response, requestType, responseType);
-        System.out.println("OK");
+        String fileAsString = new String(fileAsBytes, UTF_8);
+        Path tempFile = Paths.get("RequestBodyTest.tmp");
+        FileUtils.deleteFileIfExistsWithRetry(tempFile);
+
+        switch (responseBodyType) {
+            case BYTE_ARRAY:
+                HttpResponse<byte[]> bar = getResponse(client, request, asByteArray(), async);
+                assertEquals(bar.statusCode(), 200);
+                assertEquals(bar.body(), fileAsBytes);
+                break;
+            case BYTE_ARRAY_CONSUMER:
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                HttpResponse<Void> v = getResponse(client, request,
+                        asByteArrayConsumer(o -> consumerBytes(o, baos) ), async);
+                byte[] ba = baos.toByteArray();
+                assertEquals(v.statusCode(), 200);
+                assertEquals(ba, fileAsBytes);
+                break;
+            case DISCARD:
+                Object o = new Object();
+                HttpResponse<Object> or = getResponse(client, request, discard(o), async);
+                assertEquals(or.statusCode(), 200);
+                assertSame(or.body(), o);
+                break;
+            case FILE:
+                HttpResponse<Path> fr = getResponse(client, request, asFile(tempFile), async);
+                assertEquals(fr.statusCode(), 200);
+                assertEquals(Files.size(tempFile), fileAsString.length());
+                assertEquals(Files.readAllBytes(tempFile), fileAsBytes);
+                break;
+            case FILE_WITH_OPTION:
+                fr = getResponse(client, request, asFile(tempFile, CREATE_NEW, WRITE), async);
+                assertEquals(fr.statusCode(), 200);
+                assertEquals(Files.size(tempFile), fileAsString.length());
+                assertEquals(Files.readAllBytes(tempFile), fileAsBytes);
+                break;
+            case STRING:
+                HttpResponse<String> sr = getResponse(client, request, asString(), async);
+                assertEquals(sr.statusCode(), 200);
+                assertEquals(sr.body(), fileAsString);
+                break;
+            case STRING_WITH_CHARSET:
+                HttpResponse<String> r = getResponse(client, request, asString(StandardCharsets.UTF_8), async);
+                assertEquals(r.statusCode(), 200);
+                assertEquals(r.body(), fileAsString);
+                break;
+            default:
+                throw new AssertionError("Unknown response body:" + responseBodyType);
+        }
+    }
+
+    static <T> HttpResponse<T> getResponse(HttpClient client,
+                                           HttpRequest request,
+                                           HttpResponse.BodyHandler<T> handler,
+                                           boolean async)
+        throws InterruptedException, IOException
+    {
+        if (!async)
+            return client.send(request, handler);
+        else
+            return client.sendAsync(request, handler).join();
+    }
+
+    static byte[] getFileBytes(String path) throws IOException {
+        try (FileInputStream fis = new FileInputStream(path);
+             BufferedInputStream bis = new BufferedInputStream(fis);
+             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+            bis.transferTo(baos);
+            return baos.toByteArray();
+        }
+    }
+
+    static Supplier<FileInputStream> fileInputStreamSupplier(Path f) {
+        return new Supplier<>() {
+            Path file = f;
+            @Override
+            public FileInputStream get() {
+                try {
+                    return new FileInputStream(file.toFile());
+                } catch (FileNotFoundException x) {
+                    throw new UncheckedIOException(x);
+                }
+            }
+        };
+    }
+
+    static void consumerBytes(Optional<byte[]> bytes, ByteArrayOutputStream baos) {
+        try {
+            if (bytes.isPresent())
+                baos.write(bytes.get());
+        } catch (IOException x) {
+            throw new UncheckedIOException(x);
+        }
     }
 }
--- a/jdk/test/java/net/httpclient/Server.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/Server.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -40,7 +41,7 @@
  *
  * use interrupt() to halt
  */
-public class Server extends Thread {
+public class Server extends Thread implements Closeable {
 
     ServerSocket ss;
     private final List<Connection> sockets;
@@ -251,7 +252,11 @@
         return "http://127.0.0.1:" + port() + "/foo/";
     }
 
+    private volatile boolean closed;
+
+    @Override
     public void close() {
+        closed = true;
         try {
             ss.close();
         } catch (IOException e) {
@@ -264,13 +269,15 @@
 
     @Override
     public void run() {
-        while (true) {
+        while (!closed) {
             try {
                 Socket s = ss.accept();
                 Connection c = new Connection(s);
                 c.start();
                 additions.add(c);
             } catch (IOException e) {
+                if (closed)
+                    return;
                 e.printStackTrace();
             }
         }
--- a/jdk/test/java/net/httpclient/ShortRequestBody.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/ShortRequestBody.java	Tue Dec 13 02:04:23 2016 +0100
@@ -22,82 +22,272 @@
  */
 
 import java.io.*;
-import java.net.http.*;
-import java.net.*;
-import java.util.concurrent.*;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpResponse;
+import jdk.incubator.http.HttpRequest;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.nio.ByteBuffer;
-import java.util.function.LongConsumer;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Flow;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TimeUnit;
+import static java.lang.System.out;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 /**
  * @test
  * @bug 8151441
- * @run main/othervm/timeout=10 ShortRequestBody
+ * @summary Request body of incorrect (larger or smaller) sizes than that
+ *          reported by the body processor
+ * @run main/othervm ShortRequestBody
  */
 
-/**
- * Exception was not being thrown
- */
 public class ShortRequestBody {
 
-    static Server server;
-    static String reqbody = "Hello world";
+    static final Path testSrc = Paths.get(System.getProperty("test.src", "."));
+    static volatile HttpClient staticDefaultClient;
+
+    static HttpClient defaultClient() {
+        if (staticDefaultClient == null) {
+            synchronized (ShortRequestBody.class) {
+                staticDefaultClient = HttpClient.newHttpClient();
+            }
+        }
+        return staticDefaultClient;
+    }
+
+    // Some body types ( sources ) for testing.
+    static final String STRING_BODY = "Hello world";
+    static final byte[] BYTE_ARRAY_BODY = new byte[] {
+        (byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE };
+    static final Path FILE_BODY = testSrc.resolve("docs").resolve("files").resolve("foo.txt");
 
-    static String response = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n";
+    // Body lengths and offsets ( amount to be wrong by ), to make coordination
+    // between client and server easier.
+    static final int[] BODY_LENGTHS = new int[] { STRING_BODY.length(),
+                                                  BYTE_ARRAY_BODY.length,
+                                                  fileSize(FILE_BODY) };
+    static final int[] BODY_OFFSETS = new int[] { 0, +1, -1, +2, -2, +3, -3 };
+
+    // A delegating body processor. Subtypes will have a concrete body type.
+    static abstract class AbstractDelegateRequestBody
+            implements HttpRequest.BodyProcessor {
 
-    static class RequestBody implements HttpRequest.BodyProcessor {
-        public long onRequestStart(HttpRequest hr, LongConsumer flowController) {
-            return reqbody.length() + 1; // wrong!
+        final HttpRequest.BodyProcessor delegate;
+        final long contentLength;
+
+        AbstractDelegateRequestBody(HttpRequest.BodyProcessor delegate,
+                                    long contentLength) {
+            this.delegate = delegate;
+            this.contentLength = contentLength;
+        }
+
+        @Override
+        public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
+            delegate.subscribe(subscriber);
         }
 
-        public boolean onRequestBodyChunk(ByteBuffer buf) throws IOException {
-            byte[] b = reqbody.getBytes();
-            buf.put(b);
-            return true;
+        @Override
+        public long contentLength() { return contentLength; /* may be wrong! */ }
+    }
+
+    // Request body processors that may generate a different number of actual
+    // bytes to that of what is reported through their {@code contentLength}.
+
+    static class StringRequestBody extends AbstractDelegateRequestBody {
+        StringRequestBody(String body, int additionalLength) {
+            super(HttpRequest.BodyProcessor.fromString(body),
+                  body.getBytes(UTF_8).length + additionalLength);
+        }
+    }
+
+    static class ByteArrayRequestBody extends AbstractDelegateRequestBody {
+        ByteArrayRequestBody(byte[] body, int additionalLength) {
+            super(HttpRequest.BodyProcessor.fromByteArray(body),
+                  body.length + additionalLength);
+        }
+    }
+
+    static class FileRequestBody extends AbstractDelegateRequestBody {
+        FileRequestBody(Path path, int additionalLength) throws IOException {
+            super(HttpRequest.BodyProcessor.fromFile(path),
+                  Files.size(path) + additionalLength);
+        }
+    }
+
+    // ---
+
+    public static void main(String[] args) throws Exception {
+        try (Server server = new Server()) {
+            URI uri = new URI("http://127.0.0.1:" + server.getPort() + "/");
+
+            // sanity
+            success(uri, new StringRequestBody(STRING_BODY, 0));
+            success(uri, new ByteArrayRequestBody(BYTE_ARRAY_BODY, 0));
+            success(uri, new FileRequestBody(FILE_BODY, 0));
+
+            for (int i=1; i< BODY_OFFSETS.length; i++) {
+                failureBlocking(uri, new StringRequestBody(STRING_BODY, BODY_OFFSETS[i]));
+                failureBlocking(uri, new ByteArrayRequestBody(BYTE_ARRAY_BODY, BODY_OFFSETS[i]));
+                failureBlocking(uri, new FileRequestBody(FILE_BODY, BODY_OFFSETS[i]));
+
+                failureNonBlocking(uri, new StringRequestBody(STRING_BODY, BODY_OFFSETS[i]));
+                failureNonBlocking(uri, new ByteArrayRequestBody(BYTE_ARRAY_BODY, BODY_OFFSETS[i]));
+                failureNonBlocking(uri, new FileRequestBody(FILE_BODY, BODY_OFFSETS[i]));
+            }
+        } finally {
+            Executor def = defaultClient().executor();
+            if (def instanceof ExecutorService) {
+               ((ExecutorService)def).shutdownNow();
+            }
         }
     }
 
-    static void close(Closeable c) {
+    static void success(URI uri, HttpRequest.BodyProcessor processor)
+        throws Exception
+    {
+        CompletableFuture<HttpResponse<Void>> cf;
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(processor)
+                                         .build();
+        cf = defaultClient().sendAsync(request, discard(null));
+
+        HttpResponse<Void> resp = cf.get(30, TimeUnit.SECONDS);
+        out.println("Response code: " + resp.statusCode());
+        check(resp.statusCode() == 200, "Expected 200, got ", resp.statusCode());
+    }
+
+    static void failureNonBlocking(URI uri, HttpRequest.BodyProcessor processor)
+        throws Exception
+    {
+        CompletableFuture<HttpResponse<Void>> cf;
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(processor)
+                                         .build();
+        cf = defaultClient().sendAsync(request, discard(null));
+
         try {
-            if (c == null)
-                return;
-            c.close();
-        } catch (IOException e) {}
+            HttpResponse<Void> r = cf.get(30, TimeUnit.SECONDS);
+            throw new RuntimeException("Unexpected response: " + r.statusCode());
+        } catch (TimeoutException x) {
+            throw new RuntimeException("Unexpected timeout", x);
+        } catch (ExecutionException expected) {
+            out.println("Caught expected: " + expected);
+            check(expected.getCause() instanceof IOException,
+                  "Expected cause IOException, but got: ", expected.getCause());
+        }
+    }
+
+    static void failureBlocking(URI uri, HttpRequest.BodyProcessor processor)
+        throws Exception
+    {
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(processor)
+                                         .build();
+        try {
+            HttpResponse<Void> r = defaultClient().send(request, discard(null));
+            throw new RuntimeException("Unexpected response: " + r.statusCode());
+        } catch (IOException expected) {
+            out.println("Caught expected: " + expected);
+        }
     }
 
-    public static void main(String[] args) throws Exception {
-        ServerSocket server = new ServerSocket(0);
-        int port = server.getLocalPort();
-        URI uri = new URI("http://127.0.0.1:" + port + "/");
+    static class Server extends Thread implements AutoCloseable {
+
+        static String RESPONSE = "HTTP/1.1 200 OK\r\n" +
+                                 "Connection: close\r\n"+
+                                 "Content-length: 0\r\n\r\n";
+
+        private final ServerSocket ss;
+        private volatile boolean closed;
 
-        HttpRequest request;
-        HttpResponse r;
-        Socket s = null;
-        CompletableFuture<HttpResponse> cf1;
-        try {
-            cf1 = HttpRequest.create(uri)
-                    .body(new RequestBody())
-                    .GET()
-                    .responseAsync();
+        Server() throws IOException {
+            super("Test-Server");
+            ss = new ServerSocket(0); this.start();
+        }
+
+        int getPort() { return ss.getLocalPort(); }
+
+        @Override
+        public void run() {
+            int count = 0;
+            int offset = 0;
+
+            while (!closed) {
+                try (Socket s = ss.accept()) {
+                    InputStream is = s.getInputStream();
+                    readRequestHeaders(is);
+                    byte[] ba = new byte[1024];
 
-            s = server.accept();
-            s.getInputStream().readAllBytes();
-            try (OutputStream os = s.getOutputStream()) {
-                os.write(response.getBytes());
-            } catch (IOException ee) {
+                    int length = BODY_LENGTHS[count % 3];
+                    length += BODY_OFFSETS[offset];
+
+                    is.readNBytes(ba, 0, length);
+
+                    OutputStream os = s.getOutputStream();
+                    os.write(RESPONSE.getBytes(US_ASCII));
+                    count++;
+                    if (count % 6 == 0) // 6 is the number of failure requests per offset
+                        offset++;
+                } catch (IOException e) {
+                    if (!closed)
+                        System.out.println("Unexpected" + e);
+                }
             }
+        }
 
+        @Override
+        public void close() {
+            if (closed)
+                return;
+            closed = true;
             try {
-                r = cf1.get(3, TimeUnit.SECONDS);
-                throw new RuntimeException("Failed");
-            } catch (TimeoutException e0) {
-                throw new RuntimeException("Failed timeout");
-            } catch (ExecutionException e) {
-                System.err.println("OK");
+                ss.close();
+            } catch (IOException e) {
+                throw new UncheckedIOException("Unexpected", e);
             }
-        } finally {
-            HttpClient.getDefault().executorService().shutdownNow();
-            close(s);
-            close(server);
         }
     }
+
+    static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' };
+
+    // Read until the end of a HTTP request headers
+    static void readRequestHeaders(InputStream is) throws IOException {
+        int requestEndCount = 0, r;
+        while ((r = is.read()) != -1) {
+            if (r == requestEnd[requestEndCount]) {
+                requestEndCount++;
+                if (requestEndCount == 4) {
+                    break;
+                }
+            } else {
+                requestEndCount = 0;
+            }
+        }
+    }
+
+    static int fileSize(Path p) {
+        try { return (int) Files.size(p); }
+        catch (IOException x) { throw new UncheckedIOException(x); }
+    }
+
+    static boolean check(boolean cond, Object... failedArgs) {
+        if (cond)
+            return true;
+        // We are going to fail...
+        StringBuilder sb = new StringBuilder();
+        for (Object o : failedArgs)
+                sb.append(o);
+        throw new RuntimeException(sb.toString());
+    }
 }
--- a/jdk/test/java/net/httpclient/SmokeTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/SmokeTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,14 +24,14 @@
 /*
  * @test
  * @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          java.logging
  *          jdk.httpserver
  * @library /lib/testlibrary/ /
  * @build jdk.testlibrary.SimpleSSLContext ProxyServer EchoHandler
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
- * @run main/othervm SmokeTest
+ * @run main/othervm -Djdk.httpclient.HttpClient.log=errors,trace SmokeTest
  */
 
 import com.sun.net.httpserver.Headers;
@@ -42,19 +42,26 @@
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsParameters;
 import com.sun.net.httpserver.HttpsServer;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.net.InetSocketAddress;
 import java.net.PasswordAuthentication;
 import java.net.ProxySelector;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import java.nio.file.StandardOpenOption;
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.BufferedInputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.UncheckedIOException;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
@@ -73,8 +80,13 @@
 import java.util.List;
 import java.util.Random;
 import jdk.testlibrary.SimpleSSLContext;
-import static java.net.http.HttpRequest.*;
-import static java.net.http.HttpResponse.*;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromFile;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromInputStream;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.*;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asFile;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
+import java.util.concurrent.CountDownLatch;
 import java.util.logging.ConsoleHandler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -125,38 +137,63 @@
         while ((n=fis.read(buf)) != -1) {
             sb.append(new String(buf, 0, n, "US-ASCII"));
         }
+        fis.close();
         return sb.toString();
     }
 
+    static void cmpFileContent(Path path1, Path path2) throws IOException {
+        InputStream fis1 = new BufferedInputStream(new FileInputStream(path1.toFile()));
+        InputStream fis2 = new BufferedInputStream(new FileInputStream(path2.toFile()));
+
+        int n1, n2;
+        while ((n1=fis1.read()) != -1) {
+            n2 = fis2.read();
+            if (n1 != n2)
+                throw new IOException("Content not the same");
+        }
+        fis1.close();
+        fis2.close();
+    }
+
     public static void main(String[] args) throws Exception {
         initServer();
         fileroot = System.getProperty ("test.src", ".")+ "/docs";
         midSizedFile = Paths.get(fileroot + midSizedFilename);
         smallFile = Paths.get(fileroot + smallFilename);
-
-        client = HttpClient.create()
+        ExecutorService e = Executors.newCachedThreadPool();
+        System.out.println(e);
+        client = HttpClient.newBuilder()
                            .sslContext(ctx)
+                           .executor(e)
                            .sslParameters(sslparams)
                            .followRedirects(HttpClient.Redirect.ALWAYS)
-                           .executorService(Executors.newCachedThreadPool())
                            .build();
 
         try {
+
             test1(httproot + "files/foo.txt", true);
-
             test1(httproot + "files/foo.txt", false);
             test1(httpsroot + "files/foo.txt", true);
             test1(httpsroot + "files/foo.txt", false);
+
             test2(httproot + "echo/foo", "This is a short test");
             test2(httpsroot + "echo/foo", "This is a short test");
 
+            test2a(httproot + "echo/foo");
+            test2a(httpsroot + "echo/foo");
+
             test3(httproot + "redirect/foo.txt");
             test3(httpsroot + "redirect/foo.txt");
+
             test4(httproot + "files/foo.txt");
+
             test4(httpsroot + "files/foo.txt");
+
             test5(httproot + "echo/foo", true);
+
             test5(httpsroot + "echo/foo", true);
             test5(httproot + "echo/foo", false);
+
             test5(httpsroot + "echo/foo", false);
 
             test6(httproot + "echo/foo", true);
@@ -165,27 +202,22 @@
             test6(httpsroot + "echo/foo", false);
 
             test7(httproot + "keepalive/foo");
-
-            test8(httproot + "files/foo.txt", true);
-            test8(httproot + "files/foo.txt", false);
-            test8(httpsroot + "files/foo.txt", true);
-            test8(httpsroot + "files/foo.txt", false);
-            // disabled test9();
-
+/*
             test10(httproot + "redirecterror/foo.txt");
 
             test10(httpsroot + "redirecterror/foo.txt");
 
             test11(httproot + "echo/foo");
             test11(httpsroot + "echo/foo");
+*/
             //test12(httproot + "delay/foo", delayHandler);
 
         } finally {
             s1.stop(0);
             s2.stop(0);
             proxy.close();
+            e.shutdownNow();
             executor.shutdownNow();
-            client.executorService().shutdownNow();
         }
     }
 
@@ -209,25 +241,27 @@
         System.out.print("test1: " + target);
         URI uri = new URI(target);
 
-        HttpRequest.Builder builder = client.request(uri)
-                                             .body(noBody());
+        HttpRequest.Builder builder = HttpRequest.newBuilder().uri(uri).GET();
 
         if (fixedLen) {
             builder.header("XFixed", "yes");
         }
 
-        HttpResponse response = builder.GET().response();
+        HttpRequest request = builder.build();
 
-        String body = response.body(asString());
+        HttpResponse<String> response = client.send(request, asString());
+
+        String body = response.body();
         if (!body.equals("This is foo.txt\r\n")) {
             throw new RuntimeException();
         }
 
         // repeat async
-        response = builder.GET().responseAsync().join();
+        HttpResponse<String> response1 = client.sendAsync(request, asString())
+                                               .join();
 
-        body = response.body(asString());
-        if (!body.equals("This is foo.txt\r\n")) {
+        String body1 = response1.body();
+        if (!body1.equals("This is foo.txt\r\n")) {
             throw new RuntimeException();
         }
         System.out.println(" OK");
@@ -238,16 +272,17 @@
         System.out.print("test2: " + s);
         URI uri = new URI(s);
 
-        HttpResponse response = client.request(uri)
-                                       .body(fromString(body))
-                                       .POST()
-                                       .response();
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(fromString(body))
+                                         .build();
+
+        HttpResponse<String> response = client.send(request, asString());
 
         if (response.statusCode() != 200) {
             throw new RuntimeException(
                 "Expected 200, got [ " + response.statusCode() + " ]");
         }
-        String reply = response.body(asString());
+        String reply = response.body();
         if (!reply.equals(body)) {
             throw new RuntimeException(
                 "Body mismatch: expected [" + body + "], got [" + reply + "]");
@@ -255,6 +290,35 @@
         System.out.println(" OK");
     }
 
+    // POST use echo to check reply
+    static void test2a(String s) throws Exception {
+        System.out.print("test2a: " + s);
+        URI uri = new URI(s);
+        Path p = Util.getTempFile(128 * 1024);
+        //Path p = Util.getTempFile(1 * 1024);
+
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(fromFile(p))
+                                         .build();
+
+        Path resp = Util.getTempFile(1); // will be overwritten
+
+        HttpResponse<Path> response =
+                client.send(request,
+                            BodyHandler.asFile(resp,
+                                               StandardOpenOption.TRUNCATE_EXISTING,
+                                               StandardOpenOption.WRITE));
+
+        if (response.statusCode() != 200) {
+            throw new RuntimeException(
+                "Expected 200, got [ " + response.statusCode() + " ]");
+        }
+        Path reply = response.body();
+        //System.out.println("Reply stored in " + reply.toString());
+        cmpFileContent(reply, p);
+        System.out.println(" OK");
+    }
+
     // Redirect
     static void test3(String s) throws Exception {
         System.out.print("test3: " + s);
@@ -262,16 +326,19 @@
         RedirectHandler handler = uri.getScheme().equals("https")
                 ? redirectHandlerSecure : redirectHandler;
 
-        HttpResponse response = client.request(uri)
-                                      .body(noBody())
-                                      .GET()
-                                      .response();
+        HttpRequest request = HttpRequest.newBuilder()
+                                         .uri(uri)
+                                         .GET()
+                                         .build();
+
+        HttpResponse<Path> response = client.send(request,
+                                                  asFile(Paths.get("redir1.txt")));
 
         if (response.statusCode() != 200) {
             throw new RuntimeException(
                 "Expected 200, got [ " + response.statusCode() + " ]");
         } else {
-            response.body(HttpResponse.asFile(Paths.get("redir1.txt")));
+            response.body();
         }
 
         Path downloaded = Paths.get("redir1.txt");
@@ -284,17 +351,15 @@
 
         handler.reset();
 
-        response = client.request(uri)
-                         .body(noBody())
-                         .GET()
-                         .responseAsync()
-                         .join();
+        request = HttpRequest.newBuilder(uri).build();
+
+        response = client.sendAsync(request, asFile(Paths.get("redir2.txt"))).join();
 
         if (response.statusCode() != 200) {
             throw new RuntimeException(
                     "Expected 200, got [ " + response.statusCode() + " ]");
         } else {
-            response.body(HttpResponse.asFile(Paths.get("redir2.txt")));
+            response.body();
         }
 
         downloaded = Paths.get("redir2.txt");
@@ -312,19 +377,19 @@
         InetSocketAddress proxyAddr = new InetSocketAddress("127.0.0.1", proxyPort);
         String filename = fileroot + uri.getPath();
 
-        HttpClient cl = HttpClient.create()
+        ExecutorService e = Executors.newCachedThreadPool();
+
+        HttpClient cl = HttpClient.newBuilder()
+                                  .executor(e)
                                   .proxy(ProxySelector.of(proxyAddr))
                                   .sslContext(ctx)
                                   .sslParameters(sslparams)
                                   .build();
 
-        CompletableFuture<String> fut = cl.request(uri)
-                                          .body(noBody())
-                                          .GET()
-                                          .responseAsync()
-                                          .thenCompose((HttpResponse response) ->
-                                                          response.bodyAsync(asString())
-                                          );
+        HttpRequest request = HttpRequest.newBuilder(uri).GET().build();
+
+        CompletableFuture<String> fut = client.sendAsync(request, asString())
+                .thenApply((response) -> response.body());
 
         String body = fut.get(5, TimeUnit.HOURS);
 
@@ -334,7 +399,7 @@
             throw new RuntimeException(
                     "Body mismatch: expected [" + body + "], got [" + fc + "]");
         }
-        cl.executorService().shutdownNow();
+        e.shutdownNow();
         System.out.println(" OK");
     }
 
@@ -344,17 +409,19 @@
         URI uri = new URI(target);
         String requestBody = generateString(12 * 1024 + 13);
 
-        HttpRequest.Builder builder = client.request(uri)
+        HttpRequest.Builder builder = HttpRequest.newBuilder(uri)
                                             .expectContinue(true)
-                                            .body(fromString(requestBody));
+                                            .POST(fromString(requestBody));
 
         if (fixedLen) {
             builder.header("XFixed", "yes");
         }
 
-        HttpResponse response = builder.GET().response();
+        HttpRequest request = builder.build();
 
-        String body = response.body(asString());
+        HttpResponse<String> response = client.send(request, asString());
+
+        String body = response.body();
 
         if (!body.equals(requestBody)) {
             throw new RuntimeException(
@@ -369,21 +436,22 @@
         URI uri = new URI(target);
         String requestBody = generateString(12 * 1024 + 3);
 
-        HttpRequest.Builder builder = client.request(uri)
-                                            .body(noBody());
+        HttpRequest.Builder builder = HttpRequest.newBuilder(uri).GET();
 
         if (fixedLen) {
             builder.header("XFixed", "yes");
         }
 
-        HttpResponse response = builder.GET().response();
+        HttpRequest request = builder.build();
+
+        HttpResponse<String> response = client.send(request, asString());
 
         if (response.statusCode() != 200) {
             throw new RuntimeException(
                     "Expected 200, got [ " + response.statusCode() + " ]");
         }
 
-        String responseBody = response.body(asString());
+        String responseBody = response.body();
 
         if (responseBody.equals(requestBody)) {
             throw new RuntimeException(
@@ -395,42 +463,36 @@
     @SuppressWarnings("rawtypes")
     static void test7(String target) throws Exception {
         System.out.print("test7: " + target);
-
+        Path requestBody = Util.getTempFile(128 * 1024);
         // First test
         URI uri = new URI(target);
+        HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build();
+
         for (int i=0; i<4; i++) {
-            HttpResponse r = client.request(uri)
-                                   .body(noBody())
-                                   .GET()
-                                   .response();
-            String body = r.body(asString());
+            HttpResponse<String> r = client.send(request, asString());
+            String body = r.body();
             if (!body.equals("OK")) {
                 throw new RuntimeException("Expected OK, got: " + body);
             }
         }
 
         // Second test: 4 x parallel
-        List<CompletableFuture<HttpResponse>> futures = new LinkedList<>();
+        request = HttpRequest.newBuilder().uri(uri).POST(fromFile(requestBody)).build();
+        List<CompletableFuture<String>> futures = new LinkedList<>();
         for (int i=0; i<4; i++) {
-            futures.add(client.request(uri)
-                              .body(noBody())
-                              .GET()
-                              .responseAsync());
+            futures.add(client.sendAsync(request, asString())
+                              .thenApply((response) -> {
+                                  if (response.statusCode() == 200)
+                                      return response.body();
+                                  else
+                                      return "ERROR";
+                              }));
         }
         // all sent?
         CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                          .join();
 
-        List<CompletableFuture<String>> futureBodies = new LinkedList<>();
-        for (int i=0; i<4; i++) {
-            futureBodies.add(futures.get(i)
-                                    .join()
-                                    .bodyAsync(asString()));
-        }
-        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
-                         .join();
-
-        for (CompletableFuture<String> future : futureBodies) {
+        for (CompletableFuture<String> future : futures) {
             String body = future.get();
             if (!body.equals("OK")) {
                 throw new RuntimeException("Expected OK, got: " + body);
@@ -438,14 +500,12 @@
         }
 
         // Third test: Multiple of 4 parallel requests
+        request = HttpRequest.newBuilder(uri).GET().build();
         BlockingQueue<String> q = new LinkedBlockingQueue<>();
         for (int i=0; i<4; i++) {
-            client.request(uri)
-                  .body(noBody())
-                  .GET()
-                  .responseAsync()
-                  .thenApply((HttpResponse resp) -> {
-                      String body = resp.body(asString());
+            client.sendAsync(request, asString())
+                  .thenApply((HttpResponse<String> resp) -> {
+                      String body = resp.body();
                       putQ(q, body);
                       return body;
                   });
@@ -460,14 +520,13 @@
             if (!body.equals("OK")) {
                 throw new RuntimeException(body);
             }
-            client.request(uri)
-                  .body(noBody())
-                  .GET()
-                  .responseAsync()
-                  .thenApply((HttpResponse resp) -> {
-                      String body1 = resp.body(asString());
-                      putQ(q, body1);
-                      return body1;
+            client.sendAsync(request, asString())
+                  .thenApply((resp) -> {
+                      if (resp.statusCode() == 200)
+                          putQ(q, resp.body());
+                      else
+                          putQ(q, "ERROR");
+                      return null;
                   });
         }
         // should be four left
@@ -494,55 +553,32 @@
         }
     }
 
-    static void test8(String target, boolean fixedLen) throws Exception {
-        System.out.print("test8: " + target);
-        URI uri = new URI(target);
-
-        HttpRequest.Builder builder = client.request(uri)
-                                            .body(noBody());
-
-        if (fixedLen) {
-            builder.header("XFixed", "yes");
+    static FileInputStream newStream() {
+        try {
+            return new FileInputStream(smallFile.toFile());
+        } catch (FileNotFoundException e) {
+            throw new UncheckedIOException(e);
         }
-
-        HttpResponse response = builder.GET().response();
-
-        StringBuilder sb = new StringBuilder();
-
-        InputStream is = response.body(asInputStream());
-        int c;
-        byte[] buf = new byte[2048];
-        while ((c = is.read(buf)) != -1) {
-            for (int i=0; i<c; i++)
-                sb.append((char)buf[i]);
-        }
-        is.close();
-        String body = sb.toString();
-
-        if (!body.equals("This is foo.txt\r\n")) {
-            throw new RuntimeException("Expected \"This is foo.txt\", got: " + body);
-        }
-        System.out.println(" OK");
     }
-
     // Chunked output stream
     static void test11(String target) throws Exception {
         System.out.print("test11: " + target);
         URI uri = new URI(target);
 
-        FileInputStream file = new FileInputStream(smallFile.toFile());
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(fromInputStream(SmokeTest::newStream))
+                                         .build();
 
-        HttpRequest.Builder builder = client.request(uri)
-                                            .body(HttpRequest.fromInputStream(file));
-        HttpResponse response = builder.POST().response();
+        Path download = Paths.get("test11.txt");
+
+        HttpResponse<Path> response = client.send(request, asFile(download));
 
         if (response.statusCode() != 200) {
             throw new RuntimeException("Wrong response code");
         }
 
-        Path download = Paths.get("test11.txt");
         download.toFile().delete();
-        response.body(HttpResponse.asFile(download));
+        response.body();
 
         if (Files.size(download) != Files.size(smallFile)) {
             System.out.println("Original size: " + Files.size(smallFile));
@@ -552,80 +588,13 @@
         System.out.println(" OK");
     }
 
-    // cancel
-    /*
-    static void test12(String target, DelayHandler h) throws Exception {
-        System.out.print("test12: " + target);
-        URI uri = new URI(target);
-
-        HttpRequest.Builder builder = client
-            .request(uri)
-            .body(HttpRequest.fromString("Hello world"));
-
-        HttpRequest request = builder
-                .GET();
-        request.sendAsync();
-        h.barrier1().await();
-        // request has been processed
-        CompletableFuture<HttpResponse> cf = request.responseAsync();
-        request.cancel();
-        h.barrier2().await();
-        try {
-            HttpResponse r = cf.get();
-            throw new RuntimeException("failed 2");
-        } catch (Exception e) {
-        }
-        System.out.println(" OK");
-    }
-*/
     static void delay(int seconds) {
         try {
             Thread.sleep(seconds * 1000);
         } catch (InterruptedException e) {
         }
     }
-/*
-    // test won't work until sending fully decoupled from receiving in impl
-    static void test9() throws Exception {
-        System.out.print("test9: ");
-        UploadServer up = new UploadServer(1000 * 1000);
-        int size = up.size();
-        String u = "http://127.0.0.1:" + up.port() + "/";
-        URI uri = new URI(u);
 
-        HttpRequest request = client
-            .request(uri)
-            .body(new HttpRequestBodyProcessor() {
-                @Override
-                public ByteBuffer onRequestBodyChunk(ByteBuffer b) throws IOException {
-                    // slow things down
-                    delay(1);
-                    b.position(b.limit()); // fill it
-                    return b;
-                }
-                @Override
-                public long onRequestStart(HttpRequest req) throws IOException {
-                    return size;
-                }
-             })
-            .PUT();
-
-        CompletableFuture<HttpRequest> cf1 = request.sendAsync();
-        CompletableFuture<HttpResponse> cf = request.responseAsync();
-
-        HttpResponse resp = cf.get(1, TimeUnit.MINUTES);
-        if (resp.statusCode() != 201) {
-            throw new RuntimeException("failed: wrong response code");
-        }
-        delay(2); // allow some data to be sent
-        request.cancel();
-        delay(1);
-        if (up.failed()) {
-            throw new RuntimeException("failed to cancel request");
-        }
-        System.out.println(" OK");
-    }
-  */
     // Redirect loop: return an error after a certain number of redirects
     static void test10(String s) throws Exception {
         System.out.print("test10: " + s);
@@ -633,13 +602,12 @@
         RedirectErrorHandler handler = uri.getScheme().equals("https")
                 ? redirectErrorHandlerSecure : redirectErrorHandler;
 
-        CompletableFuture<HttpResponse> cf = client.request(uri)
-                                                   .body(noBody())
-                                                   .GET()
-                                                   .responseAsync();
+        HttpRequest request = HttpRequest.newBuilder(uri).GET().build();
+        CompletableFuture<HttpResponse<String>> cf =
+                client.sendAsync(request, asString());
 
         try {
-            HttpResponse response = cf.join();
+            HttpResponse<String> response = cf.join();
             throw new RuntimeException("Exepected Completion Exception");
         } catch (CompletionException e) {
             //System.out.println(e);
@@ -667,10 +635,11 @@
     }
 
     static void initServer() throws Exception {
+
         Logger logger = Logger.getLogger("com.sun.net.httpserver");
         ConsoleHandler ch = new ConsoleHandler();
-        logger.setLevel(Level.ALL);
-        ch.setLevel(Level.ALL);
+        logger.setLevel(Level.SEVERE);
+        ch.setLevel(Level.SEVERE);
         logger.addHandler(ch);
 
         String root = System.getProperty ("test.src")+ "/docs";
@@ -882,6 +851,23 @@
             }
         }
     }
+
+    static Path getTempFile(int size) throws IOException {
+        File f = File.createTempFile("test", "txt");
+        f.deleteOnExit();
+        byte[] buf = new byte[2048];
+        for (int i=0; i<buf.length; i++)
+            buf[i] = (byte)i;
+
+        FileOutputStream fos = new FileOutputStream(f);
+        while (size > 0) {
+            int amount = Math.min(size, buf.length);
+            fos.write(buf, 0, amount);
+            size -= amount;
+        }
+        fos.close();
+        return f.toPath();
+    }
 }
 
 class DelayHandler implements HttpHandler {
@@ -918,11 +904,12 @@
 // Then send 4 requests in parallel x 100 times (same four addresses used all time)
 
 class KeepAliveHandler implements HttpHandler {
-    volatile int counter = 0;
+    AtomicInteger counter = new AtomicInteger(0);
+    AtomicInteger nparallel = new AtomicInteger(0);
 
     HashSet<Integer> portSet = new HashSet<>();
 
-    volatile int[] ports = new int[4];
+    int[] ports = new int[8];
 
     void sleep(int n) {
         try {
@@ -930,47 +917,74 @@
         } catch (InterruptedException e) {}
     }
 
+    synchronized void setPort(int index, int value) {
+        ports[index] = value;
+    }
+
+    synchronized int getPort(int index) {
+        return ports[index];
+    }
+
+    synchronized void getPorts(int[] dest, int from) {
+        dest[0] = ports[from+0];
+        dest[1] = ports[from+1];
+        dest[2] = ports[from+2];
+        dest[3] = ports[from+3];
+    }
+
+    static CountDownLatch latch = new CountDownLatch(4);
+
     @Override
-    public synchronized void handle (HttpExchange t)
+    public void handle (HttpExchange t)
         throws IOException
     {
+        int np = nparallel.incrementAndGet();
         int remotePort = t.getRemoteAddress().getPort();
         String result = "OK";
+        int[] lports = new int[4];
 
-        int n = counter++;
+        int n = counter.getAndIncrement();
+
         /// First test
         if (n < 4) {
-            ports[n] = remotePort;
+            setPort(n, remotePort);
         }
         if (n == 3) {
+            getPorts(lports, 0);
             // check all values in ports[] are the same
-            if (ports[0] != ports[1] || ports[2] != ports[3]
-                    || ports[0] != ports[2]) {
+            if (lports[0] != lports[1] || lports[2] != lports[3]
+                    || lports[0] != lports[2]) {
                 result = "Error " + Integer.toString(n);
                 System.out.println(result);
             }
         }
         // Second test
         if (n >=4 && n < 8) {
-            // delay to ensure ports are different
-            sleep(500);
-            ports[n-4] = remotePort;
+            // delay so that this connection doesn't get reused
+            // before all 4 requests sent
+            setPort(n, remotePort);
+            latch.countDown();
+            try {latch.await();} catch (InterruptedException e) {}
         }
         if (n == 7) {
+            getPorts(lports, 4);
             // should be all different
-            if (ports[0] == ports[1] || ports[2] == ports[3]
-                    || ports[0] == ports[2]) {
+            if (lports[0] == lports[1] || lports[2] == lports[3]
+                    || lports[0] == lports[2]) {
                 result = "Error " + Integer.toString(n);
                 System.out.println(result);
-                System.out.printf("Ports: %d, %d, %d, %d\n", ports[0], ports[1], ports[2], ports[3]);
             }
             // setup for third test
             for (int i=0; i<4; i++) {
-                portSet.add(ports[i]);
+                portSet.add(lports[i]);
             }
+            System.out.printf("Ports: %d, %d, %d, %d\n", lports[0], lports[1], lports[2], lports[3]);
         }
         // Third test
         if (n > 7) {
+            if (np > 4) {
+                System.err.println("XXX np = " + np);
+            }
             // just check that port is one of the ones in portSet
             if (!portSet.contains(remotePort)) {
                 System.out.println ("UNEXPECTED REMOTE PORT " + remotePort);
@@ -987,5 +1001,6 @@
         OutputStream o = t.getResponseBody();
         o.write(result.getBytes("US-ASCII"));
         t.close();
+        nparallel.getAndDecrement();
     }
 }
--- a/jdk/test/java/net/httpclient/SplitResponse.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/SplitResponse.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,14 +21,16 @@
  * questions.
  */
 
-//package javaapplication16;
 
 import java.io.IOException;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
 import java.net.URI;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
 /**
  * @test
@@ -71,29 +73,34 @@
         URI uri = new URI(server.getURL());
         server.start();
 
-        HttpRequest request;
-        HttpResponse r;
-        CompletableFuture<HttpResponse> cf1;
+        HttpClient client = HttpClient.newHttpClient();
+        HttpRequest request = HttpRequest.newBuilder(uri).build();
+        HttpResponse<String> r;
+        CompletableFuture<HttpResponse<String>> cf1;
 
-        for (int i=0; i<responses.length; i++) {
-            cf1 = HttpRequest.create(uri)
-                    .GET()
-                    .responseAsync();
-            String body = responses[i];
+        try {
+            for (int i=0; i<responses.length; i++) {
+                cf1 = client.sendAsync(request, asString());
+                String body = responses[i];
 
-            Server.Connection c = server.activity();
-            sendSplitResponse(response(body), c);
-            r = cf1.get();
-            if (r.statusCode()!= 200)
-                throw new RuntimeException("Failed");
+                Server.Connection c = server.activity();
+                sendSplitResponse(response(body), c);
+                r = cf1.get();
+                if (r.statusCode()!= 200)
+                    throw new RuntimeException("Failed");
 
-            String rxbody = r.body(HttpResponse.asString());
-            System.out.println("received " + rxbody);
-            if (!rxbody.equals(body))
-                throw new RuntimeException("Failed");
-            c.close();
+                String rxbody = r.body();
+                System.out.println("received " + rxbody);
+                if (!rxbody.equals(body))
+                    throw new RuntimeException("Failed");
+                c.close();
+            }
+        } finally {
+            Executor def = client.executor();
+            if (def instanceof ExecutorService) {
+                ((ExecutorService)def).shutdownNow();
+            }
         }
-        HttpClient.getDefault().executorService().shutdownNow();
         System.out.println("OK");
     }
 
--- a/jdk/test/java/net/httpclient/TEST.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/TEST.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,1 +1,1 @@
-modules = java.httpclient
+modules = jdk.incubator.httpclient
--- a/jdk/test/java/net/httpclient/TestKit.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/TestKit.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,8 +21,21 @@
  * questions.
  */
 
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Supplier;
 import java.util.regex.Pattern;
 
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singleton;
 import static java.util.Objects.requireNonNull;
 
 //
@@ -50,7 +63,7 @@
         }
     }
 
-    public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
+    public static <T extends Throwable> T assertThrows(Class<T> clazz,
                                                        ThrowingProcedure code) {
         requireNonNull(clazz, "clazz");
         requireNonNull(code, "code");
@@ -80,7 +93,7 @@
     // The rationale behind asking for a regex is to not pollute variable names
     // space in the scope of assertion: if it's something as simple as checking
     // a message, we can do it inside
-    public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
+    public static <T extends Throwable> T assertThrows(Class<T> clazz,
                                                        String messageRegex,
                                                        ThrowingProcedure code) {
         requireNonNull(messageRegex, "messagePattern");
@@ -98,4 +111,133 @@
         }
         return t;
     }
+
+    /*
+     * Asserts that the given Collection is unmodifiable: any mutator method
+     * throw an UnsupportedOperationException unconditionally.
+     */
+    public static void assertUnmodifiableCollection(Collection<?> collection) {
+        assertUnmodifiableCollection(collection, () -> null);
+    }
+
+    public static <E> void assertUnmodifiableCollection(Collection<E> collection,
+                                                        Supplier<? extends E> elementsFactory) {
+        requireNonNull(collection, "collection");
+        requireNonNull(elementsFactory, "elementsFactory");
+
+        E e = elementsFactory.get();
+
+        assertUOE(() -> collection.add(e));
+        assertUOE(() -> collection.addAll(singleton(e)));
+        Iterator<?> i = collection.iterator();
+        if (i.hasNext()) {
+            i.next();
+            assertUOE(i::remove);
+        }
+        assertUOE(collection::clear);
+        assertUOE(() -> collection.remove(e));
+        assertUOE(() -> collection.removeAll(singleton(e)));
+        assertUOE(() -> collection.removeIf(x -> true));
+        assertUOE(() -> collection.retainAll(emptyList()));
+        // No need to check toArray methods, since API guarantees arrays
+        // returned by them are "safe"
+    }
+
+    public static void assertUnmodifiableSet(Set<?> set) {
+        assertUnmodifiableCollection(set, () -> null);
+    }
+
+    public static <E> void assertUnmodifiableSet(Set<E> set,
+                                                 Supplier<? extends E> elementsFactory) {
+        assertUnmodifiableCollection(set, elementsFactory);
+    }
+
+    public static void assertUnmodifiableList(List<?> list) {
+        assertUnmodifiableList(list, () -> null);
+    }
+
+    public static <E> void assertUnmodifiableList(List<E> list,
+                                                  Supplier<? extends E> elementsFactory) {
+        assertUnmodifiableList(list, elementsFactory, 3); // This list, its sublist and its sublist's sublist
+    }
+
+    private static <E> void assertUnmodifiableList(List<E> list,
+                                                   Supplier<? extends E> elementsFactory,
+                                                   int depth) {
+        requireNonNull(list, "list");
+        requireNonNull(elementsFactory, "elementsFactory");
+        if (depth < 0) {
+            throw new IllegalArgumentException("depth: " + depth);
+        }
+        if (depth == 0) {
+            return;
+        }
+
+        E e = elementsFactory.get();
+
+        assertUnmodifiableCollection(list, elementsFactory);
+        assertUOE(() -> list.add(0, e));
+        assertUOE(() -> list.addAll(0, singleton(e)));
+
+        ListIterator<E> i = list.listIterator();
+        if (i.hasNext()) {
+            i.next();
+            assertUOE(i::remove);
+            assertUOE(() -> i.set(e));
+            assertUOE(() -> i.add(e));
+        }
+        assertUOE(() -> list.remove((int) 0));
+        assertUOE(() -> list.replaceAll(x -> e));
+        assertUOE(() -> list.set(0, e));
+
+        // Any non-null general-purpose Comparator would do
+        Comparator<Object> comparator = (a, b) -> Objects.hash(a, b);
+        assertUOE(() -> list.sort(comparator));
+
+        assertUnmodifiableList(list.subList(0, list.size()), elementsFactory, depth - 1);
+    }
+
+    public static void assertUnmodifiableMap(Map<?, ?> map) {
+        assertUnmodifiableMap(map, () -> new AbstractMap.SimpleImmutableEntry<>(null, null));
+    }
+
+    public static <K, V> void assertUnmodifiableMap(Map<K, V> map,
+                                                    Supplier<? extends Map.Entry<? extends K, ? extends V>> entriesFactory) {
+        requireNonNull(map, "map");
+        requireNonNull(entriesFactory, "entriesFactory");
+        assertUOE(map::clear);
+
+        Map.Entry<? extends K, ? extends V> e1 = entriesFactory.get();
+        K k = e1.getKey();
+        V v = e1.getValue();
+
+        assertUOE(() -> map.compute(k, (k1, v1) -> v));
+        assertUOE(() -> map.computeIfAbsent(k, (k1) -> v));
+        assertUOE(() -> map.computeIfPresent(k, (k1, v1) -> v));
+
+        Set<Map.Entry<K, V>> entrySet = map.entrySet();
+        assertUnmodifiableSet(entrySet);
+        for (Map.Entry<K, V> e : entrySet) {
+            assertUOE(() -> e.setValue(null));
+        }
+
+        assertUnmodifiableSet(map.keySet());
+        assertUOE(() -> map.merge(k, v, (k1, v1) -> v));
+        assertUOE(() -> map.put(k, v));
+        // Map.of(k, v) wouldn't do, as it doesn't permit nulls
+        Map<K, V> m = new HashMap<>();
+        m.put(k, v);
+        assertUOE(() -> map.putAll(m));
+        assertUOE(() -> map.putIfAbsent(k, v));
+        assertUOE(() -> map.remove(k));
+        assertUOE(() -> map.remove(k, v));
+        assertUOE(() -> map.replace(k, v));
+        assertUOE(() -> map.replace(k, v, v));
+        assertUOE(() -> map.replaceAll((k1, v1) -> v));
+        assertUnmodifiableCollection(map.values());
+    }
+
+    public static void assertUOE(ThrowingProcedure code) {
+        assertThrows(UnsupportedOperationException.class, code);
+    }
 }
--- a/jdk/test/java/net/httpclient/TestKitTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/TestKitTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,8 +21,16 @@
  * questions.
  */
 
+import org.testng.annotations.Test;
+
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.IllegalFormatException;
+import java.util.LinkedList;
+import java.util.Map;
 import java.util.Set;
 
 import static org.testng.Assert.assertEquals;
@@ -37,12 +45,8 @@
  */
 public final class TestKitTest {
 
-    public static void main(String[] args) {
-        testAssertNotThrows();
-        testAssertThrows();
-    }
-
-    private static void testAssertNotThrows() {
+    @Test
+    public void testAssertNotThrows() {
         Integer integer = TestKit.assertNotThrows(
                 () -> TestKit.assertNotThrows(() -> 1)
         );
@@ -69,7 +73,8 @@
                         + "java.io.IOException");
     }
 
-    private static void testAssertThrows() {
+    @Test
+    public void testAssertThrows() {
         NullPointerException npe = TestKit.assertThrows(
                 NullPointerException.class,
                 () -> TestKit.assertThrows(null, null)
@@ -127,4 +132,21 @@
                 "Expected to catch an exception of type java.util.IllegalFormatException"
                         + ", but caught java.lang.IndexOutOfBoundsException");
     }
+
+    @Test
+    public void testAssertUnmodifiable() {
+        TestKit.assertUnmodifiableList(
+                Collections.unmodifiableList(
+                        new ArrayList<>(Arrays.asList(1, 2, 3))));
+        TestKit.assertThrows(RuntimeException.class,
+                () -> TestKit.assertUnmodifiableList(new ArrayList<>()));
+        TestKit.assertThrows(RuntimeException.class,
+                () -> TestKit.assertUnmodifiableList(new LinkedList<>()));
+        TestKit.assertThrows(RuntimeException.class,
+                () -> TestKit.assertUnmodifiableList(
+                        new ArrayList<>(Arrays.asList(1, 2, 3))));
+        TestKit.assertUnmodifiableMap(Collections.unmodifiableMap(Map.of()));
+        TestKit.assertThrows(RuntimeException.class,
+                () -> TestKit.assertUnmodifiableMap(new HashMap<>()));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/TimeoutBasic.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import jdk.incubator.http.HttpTimeoutException;
+import java.time.Duration;
+import java.util.List;
+import java.util.concurrent.*;
+
+import static java.lang.System.out;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
+
+/**
+ * @test
+ * @summary Basic tests for response timeouts
+ * @run main/othervm TimeoutBasic
+ * @ignore
+ */
+
+public class TimeoutBasic {
+
+    static List<Duration> TIMEOUTS = List.of(/*Duration.ofSeconds(1),
+                                             Duration.ofMillis(100),*/
+                                             Duration.ofNanos(99)
+                                            /* Duration.ofNanos(1)*/);
+
+    public static void main(String[] args) throws Exception {
+        HttpClient client = HttpClient.newHttpClient();
+        try (ServerSocket ss = new ServerSocket(0, 20)) {
+            int port = ss.getLocalPort();
+            URI uri = new URI("http://127.0.0.1:" + port + "/");
+
+//            out.println("--- TESTING Async");
+//            for (Duration duration : TIMEOUTS) {
+//                out.println("  with duration of " + duration);
+//                HttpRequest request = HttpRequest.newBuilder(uri)
+//                                                 .timeout(duration)
+//                                                 .GET().build();
+//                try {
+//                    HttpResponse<?> resp = client.sendAsync(request, discard(null)).join();
+//                    throw new RuntimeException("Unexpected response: " + resp.statusCode());
+//                } catch (CompletionException e) {
+//                    if (!(e.getCause() instanceof HttpTimeoutException)) {
+//                        throw new RuntimeException("Unexpected exception: " + e.getCause());
+//                    } else {
+//                        out.println("Caught expected timeout: " + e.getCause());
+//                    }
+//                }
+//            }
+
+            out.println("--- TESTING Sync");
+            for (Duration duration : TIMEOUTS) {
+                out.println("  with duration of " + duration);
+                HttpRequest request = HttpRequest.newBuilder(uri)
+                                                 .timeout(duration)
+                                                 .GET()
+                                                 .build();
+                try {
+                    client.send(request, discard(null));
+                } catch (HttpTimeoutException e) {
+                    out.println("Caught expected timeout: " + e);
+                }
+            }
+        } finally {
+            ((ExecutorService) client.executor()).shutdownNow();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/TimeoutOrdering.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import jdk.incubator.http.HttpTimeoutException;
+import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import static java.lang.System.out;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
+
+/**
+ * @test
+ * @key intermittent
+ * @summary Ensures that timeouts of multiple requests are handled in correct order
+ * @run main/othervm TimeoutOrdering
+ */
+
+public class TimeoutOrdering {
+
+    // The assumption is that 5 secs is sufficiently large enough, without being
+    // too large, to ensure the correct receive order of HttpTimeoutExceptions.
+    static int[] TIMEOUTS = {10, 5, 15, 10, 10, 5};
+
+    // A queue for placing timed out requests so that their order can be checked.
+    static LinkedBlockingQueue<HttpRequest> queue = new LinkedBlockingQueue<>();
+
+    static volatile boolean error;
+
+    public static void main(String[] args) throws Exception {
+        HttpClient client = HttpClient.newHttpClient();
+
+        try (ServerSocket ss = new ServerSocket(0, 20)) {
+            int port = ss.getLocalPort();
+            URI uri = new URI("http://127.0.0.1:" + port + "/");
+
+            HttpRequest[] requests = new HttpRequest[TIMEOUTS.length];
+
+            out.println("--- TESTING Async");
+            for (int i = 0; i < TIMEOUTS.length; i++) {
+                requests[i] = HttpRequest.newBuilder(uri)
+                                         .timeout(Duration.ofSeconds(TIMEOUTS[i]))
+                                         .GET()
+                                         .build();
+
+                final HttpRequest req = requests[i];
+                CompletableFuture<HttpResponse<Object>> response = client
+                    .sendAsync(req, discard(null))
+                    .whenComplete((HttpResponse<Object> r, Throwable t) -> {
+                        if (r != null) {
+                            out.println("Unexpected response: " + r);
+                            error = true;
+                        }
+                        if (t != null) {
+                            if (!(t.getCause() instanceof HttpTimeoutException)) {
+                                out.println("Wrong exception type:" + t.toString());
+                                error = true;
+                            } else {
+                                out.println("Caught expected timeout: " + t.getCause());
+                            }
+                        }
+                        queue.add(req);
+                    });
+            }
+            System.out.println("All requests submitted. Waiting ...");
+
+            checkReturnOrder(requests);
+
+            if (error)
+                throw new RuntimeException("Failed. Check output");
+
+            // Repeat blocking in separate threads. Use queue to wait.
+            out.println("--- TESTING Sync");
+
+            // For running blocking response tasks
+            ExecutorService executor = Executors.newCachedThreadPool();
+
+            for (int i = 0; i < TIMEOUTS.length; i++) {
+                requests[i] = HttpRequest.newBuilder(uri)
+                                         .timeout(Duration.ofSeconds(TIMEOUTS[i]))
+                                         .GET()
+                                         .build();
+
+                final HttpRequest req = requests[i];
+                executor.execute(() -> {
+                    try {
+                        client.send(req, discard(null));
+                    } catch (HttpTimeoutException e) {
+                        out.println("Caught expected timeout: " + e);
+                        queue.offer(req);
+                    } catch (IOException | InterruptedException ee) {
+                        error = true;
+                    }
+                });
+            }
+            System.out.println("All requests submitted. Waiting ...");
+
+            checkReturnOrder(requests);
+
+            executor.shutdownNow();
+
+            if (error)
+                throw new RuntimeException("Failed. Check output");
+
+        } finally {
+            ((ExecutorService) client.executor()).shutdownNow();
+        }
+    }
+
+    static void checkReturnOrder(HttpRequest[] requests) throws InterruptedException {
+        // wait for exceptions and check order
+        for (int j = 0; j < TIMEOUTS.length; j++) {
+            HttpRequest req = queue.take();
+            out.println("Got request from queue " + req + ", order: " + getRequest(req, requests));
+            switch (j) {
+                case 0:
+                case 1:  // Expect shortest timeouts, 5sec, first.
+                    if (!(req == requests[1] || req == requests[5])) {
+                        String s = "Expected r1 or r5. Got: " + getRequest(req, requests);
+                        throw new RuntimeException(s);
+                    }
+                    break;
+                case 2:
+                case 3:
+                case 4: // Expect medium timeouts, 10sec, next.
+                    if (!(req == requests[0] || req == requests[3] || req == requests[4])) {
+                        String s = "Expected r1, r4 or r5. Got: " + getRequest(req, requests);
+                        throw new RuntimeException(s);
+                    }
+                    break;
+                case 5:  // Expect largest timeout, 15sec, last.
+                    if (req != requests[2]) {
+                        String s= "Expected r3. Got: " + getRequest(req, requests);
+                        throw new RuntimeException(s);
+                    }
+                    break;
+                default:
+                    throw new AssertionError("Unknown index: " + j);
+            }
+        }
+        out.println("Return order ok");
+    }
+
+    /** Returns the index of the request in the array. */
+    static String getRequest(HttpRequest req, HttpRequest[] requests) {
+        for (int i=0; i<requests.length; i++) {
+            if (req == requests[i]) {
+                return "r" + i;
+            }
+        }
+        throw new AssertionError("Unknown request: " + req);
+    }
+}
--- a/jdk/test/java/net/httpclient/TimeoutTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.net.http.HttpTimeoutException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @test
- * @bug 8087112
- * @run main/othervm TimeoutTest
- */
-
-public class TimeoutTest {
-
-    static int[] timeouts = {6, 4, 8, 6, 6, 4};
-    static HttpRequest[] rqs = new HttpRequest[timeouts.length];
-    static LinkedBlockingQueue<HttpRequest> queue = new LinkedBlockingQueue<>();
-    static volatile boolean error = false;
-    static ExecutorService executor = Executors.newCachedThreadPool();
-
-    public static void main(String[] args) throws Exception {
-        try {
-            dotest();
-        } finally {
-            HttpClient.getDefault().executorService().shutdownNow();
-            executor.shutdownNow();
-        }
-    }
-    public static void dotest() throws Exception {
-        System.out.println("Test takes over 40 seconds");
-        ServerSocket ss = new ServerSocket(0, 20);
-        int port = ss.getLocalPort();
-
-        URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/foo");
-        int i = 0;
-        for (int timeout : timeouts) {
-            HttpRequest request;
-            (request = rqs[i] = HttpRequest.create(uri)
-                .timeout(TimeUnit.SECONDS, timeout)
-                .GET())
-                .responseAsync()
-                .whenComplete((HttpResponse r, Throwable t) -> {
-                    if (!(t.getCause() instanceof HttpTimeoutException)) {
-                        System.out.println("Wrong exception type:" + t.toString());
-                        error = true;
-                    }
-                    if (t != null) {
-                        queue.add(request);
-                    }
-                })
-                .thenAccept((HttpResponse r) -> {
-                    r.bodyAsync(HttpResponse.ignoreBody());
-                });
-            i++;
-        }
-
-        System.out.println("SUBMITTED");
-
-        checkReturnOrder();
-
-        if (error)
-            throw new RuntimeException("Failed");
-
-        // Repeat blocking in separate threads. Use queue to wait.
-        System.out.println("DOING BLOCKING");
-
-        i = 0;
-        for (int timeout : timeouts) {
-            HttpRequest req = HttpRequest.create(uri)
-                .timeout(TimeUnit.SECONDS, timeout)
-                .GET();
-            rqs[i] = req;
-            executor.execute(() -> {
-                try {
-                    req.response().body(HttpResponse.ignoreBody());
-                } catch (HttpTimeoutException e) {
-                    queue.offer(req);
-                } catch (IOException | InterruptedException ee) {
-                    error = true;
-                }
-            });
-            i++;
-        }
-
-        checkReturnOrder();
-
-        if (error)
-            throw new RuntimeException("Failed");
-    }
-
-    static void checkReturnOrder() throws InterruptedException {
-        // wait for exceptions and check order
-        for (int j = 0; j < timeouts.length; j++) {
-            HttpRequest req = queue.take();
-            switch (j) {
-                case 0:
-                case 1:
-                    if (req != rqs[1] && req != rqs[5]) {
-                        System.out.printf("Expected 1 or 5. Got %s\n", getRequest(req));
-                        throw new RuntimeException("Error");
-                    }
-                    break;
-                case 2:
-                case 3:
-                case 4:
-                    if (req != rqs[0] && req != rqs[3] && req != rqs[4]) {
-                        System.out.printf("Expected r1, r4 or r5. Got %s\n", getRequest(req));
-                        throw new RuntimeException("Error");
-                    }
-                    break;
-                case 5:
-                    if (req != rqs[2]) {
-                        System.out.printf("Expected r3. Got %s\n", getRequest(req));
-                        throw new RuntimeException("Error");
-                    }
-            }
-        }
-        System.out.println("Return order ok");
-    }
-
-    static String getRequest(HttpRequest req) {
-        for (int i=0; i<rqs.length; i++) {
-            if (req == rqs[i]) {
-                return "[" + Integer.toString(i) + "]";
-            }
-        }
-        return "unknown";
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/examples/WebSocketExample.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.InetSocketAddress;
+import java.net.ProxySelector;
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.WebSocket;
+
+/*
+ * THE CONTENTS OF THIS FILE HAVE TO BE IN SYNC WITH THE EXAMPLES USED IN THE
+ * JAVADOC OF WEBSOCKET TYPE
+ *
+ * @test
+ * @compile WebSocketExample.java
+ */
+public class WebSocketExample {
+
+    WebSocket.Listener listener = new WebSocket.Listener() {
+        // ...
+    };
+
+    public void newBuilderExample0() {
+        HttpClient client = HttpClient.newHttpClient();
+        WebSocket.Builder builder = client.newWebSocketBuilder(
+                URI.create("ws://websocket.example.com"),
+                listener);
+    }
+
+    public void newBuilderExample1() {
+        InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
+        HttpClient client = HttpClient.newBuilder()
+                .proxy(ProxySelector.of(addr))
+                .build();
+        WebSocket.Builder builder = client.newWebSocketBuilder(
+                URI.create("ws://websocket.example.com"),
+                listener);
+    }
+}
--- a/jdk/test/java/net/httpclient/http2/BasicTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/BasicTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,34 +24,27 @@
 /*
  * @test
  * @bug 8087112
- * @key intermittent
- * @library /lib/testlibrary
+ * @library /lib/testlibrary server
  * @build jdk.testlibrary.SimpleSSLContext
- * @modules java.httpclient
- * @compile/module=java.httpclient java/net/http/BodyOutputStream.java
- * @compile/module=java.httpclient java/net/http/BodyInputStream.java
- * @compile/module=java.httpclient java/net/http/EchoHandler.java
- * @compile/module=java.httpclient java/net/http/Http2Handler.java
- * @compile/module=java.httpclient java/net/http/Http2TestExchange.java
- * @compile/module=java.httpclient java/net/http/Http2TestServerConnection.java
- * @compile/module=java.httpclient java/net/http/Http2TestServer.java
- * @compile/module=java.httpclient java/net/http/OutgoingPushPromise.java
- * @compile/module=java.httpclient java/net/http/TestUtil.java
- * @run testng/othervm -Djava.net.http.HttpClient.log=ssl,requests,responses,errors BasicTest
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
+ * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors BasicTest
  */
 
-import java.io.*;
 import java.net.*;
-import java.net.http.*;
-import static java.net.http.HttpClient.Version.HTTP_2;
+import jdk.incubator.http.*;
+import static jdk.incubator.http.HttpClient.Version.HTTP_2;
 import javax.net.ssl.*;
 import java.nio.file.*;
 import java.util.concurrent.*;
 import jdk.testlibrary.SimpleSSLContext;
-
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromFile;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asFile;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
 import org.testng.annotations.Test;
-import org.testng.annotations.Parameters;
 
 @Test
 public class BasicTest {
@@ -68,19 +61,16 @@
             SimpleSSLContext sslct = new SimpleSSLContext();
             sslContext = sslct.get();
             client = getClient();
-            exec = client.executorService();
-            httpServer = new Http2TestServer(false, 0, new EchoHandler(),
-                    exec, sslContext);
+            httpServer = new Http2TestServer(false, 0, exec, sslContext);
+            httpServer.addHandler(new EchoHandler(), "/");
             httpPort = httpServer.getAddress().getPort();
 
-            httpsServer = new Http2TestServer(true, 0, new EchoHandler(),
-                    exec, sslContext);
+            httpsServer = new Http2TestServer(true, 0, exec, sslContext);
+            httpsServer.addHandler(new EchoHandler(), "/");
 
             httpsPort = httpsServer.getAddress().getPort();
-            httpURIString = "http://127.0.0.1:" + Integer.toString(httpPort) +
-                    "/foo/";
-            httpsURIString = "https://127.0.0.1:" + Integer.toString(httpsPort) +
-                    "/bar/";
+            httpURIString = "http://127.0.0.1:" + httpPort + "/foo/";
+            httpsURIString = "https://127.0.0.1:" + httpsPort + "/bar/";
 
             httpServer.start();
             httpsServer.start();
@@ -91,7 +81,7 @@
         }
     }
 
-    @Test(timeOut=30000)
+    @Test(timeOut=3000000)
     public static void test() throws Exception {
         try {
             initialize();
@@ -101,6 +91,9 @@
             streamTest(true);
             paramsTest();
             Thread.sleep(1000 * 4);
+        } catch (Throwable tt) {
+            System.err.println("tt caught");
+            tt.printStackTrace();
         } finally {
             httpServer.stop();
             httpsServer.stop();
@@ -110,10 +103,12 @@
 
     static HttpClient getClient() {
         if (client == null) {
-            client = HttpClient.create()
-                .sslContext(sslContext)
-                .version(HTTP_2)
-                .build();
+            exec = Executors.newCachedThreadPool();
+            client = HttpClient.newBuilder()
+                               .executor(exec)
+                               .sslContext(sslContext)
+                               .version(HTTP_2)
+                               .build();
         }
         return client;
     }
@@ -142,48 +137,44 @@
     }
 
     static Void compareFiles(Path path1, Path path2) {
-        return java.net.http.TestUtil.compareFiles(path1, path2);
+        return TestUtil.compareFiles(path1, path2);
     }
 
     static Path tempFile() {
-        return java.net.http.TestUtil.tempFile();
+        return TestUtil.tempFile();
     }
 
     static final String SIMPLE_STRING = "Hello world Goodbye world";
 
     static final int LOOPS = 13;
-    static final int FILESIZE = 64 * 1024;
+    static final int FILESIZE = 64 * 1024 + 200;
 
     static void streamTest(boolean secure) throws Exception {
         URI uri = getURI(secure);
         System.err.printf("streamTest %b to %s\n" , secure, uri);
 
         HttpClient client = getClient();
-        Path src = java.net.http.TestUtil.getAFile(FILESIZE * 4);
-        HttpRequest req = client.request(uri)
-                .body(HttpRequest.fromFile(src))
-                .POST();
+        Path src = TestUtil.getAFile(FILESIZE * 4);
+        HttpRequest req = HttpRequest.newBuilder(uri)
+                                     .POST(fromFile(src))
+                                     .build();
 
-        CompletableFuture<InputStream> response = req.responseAsync()
-                .thenCompose(resp -> {
+        Path dest = Paths.get("streamtest.txt");
+        dest.toFile().delete();
+        CompletableFuture<Path> response = client.sendAsync(req, asFile(dest))
+                .thenApply(resp -> {
                     if (resp.statusCode() != 200)
                         throw new RuntimeException();
-                    return resp.bodyAsync(HttpResponse.asInputStream());
+                    return resp.body();
                 });
-        InputStream is = response.join();
-        File dest = File.createTempFile("foo","bar");
-        dest.deleteOnExit();
-        FileOutputStream os = new FileOutputStream(dest);
-        is.transferTo(os);
-        is.close();
-        os.close();
-        int count = 0;
-        compareFiles(src, dest.toPath());
+        response.join();
+        compareFiles(src, dest);
         System.err.println("DONE");
     }
 
     static void paramsTest() throws Exception {
-        Http2TestServer server = new Http2TestServer(true, 0, (t -> {
+        Http2TestServer server = new Http2TestServer(true, 0, exec, sslContext);
+        server.addHandler((t -> {
             SSLSession s = t.getSSLSession();
             String prot = s.getProtocol();
             if (prot.equals("TLSv1.2")) {
@@ -192,14 +183,13 @@
                 System.err.printf("Protocols =%s\n", prot);
                 t.sendResponseHeaders(500, -1);
             }
-        }), exec, sslContext);
+        }), "/");
         server.start();
         int port = server.getAddress().getPort();
         URI u = new URI("https://127.0.0.1:"+port+"/foo");
         HttpClient client = getClient();
-        HttpRequest req = client.request(u)
-            .GET();
-        HttpResponse resp = req.response();
+        HttpRequest req = HttpRequest.newBuilder(u).build();
+        HttpResponse<String> resp = client.send(req, asString());
         int stat = resp.statusCode();
         if (stat != 200) {
             throw new RuntimeException("paramsTest failed "
@@ -214,15 +204,15 @@
         // Do a simple warmup request
 
         HttpClient client = getClient();
-        HttpRequest req = client.request(uri)
-                .body(HttpRequest.fromString(SIMPLE_STRING))
-                .POST();
-        HttpResponse response = req.response();
+        HttpRequest req = HttpRequest.newBuilder(uri)
+                                     .POST(fromString(SIMPLE_STRING))
+                                     .build();
+        HttpResponse<String> response = client.send(req, asString());
         HttpHeaders h = response.headers();
 
         checkStatus(200, response.statusCode());
 
-        String responseBody = response.body(HttpResponse.asString());
+        String responseBody = response.body();
         checkStrings(SIMPLE_STRING, responseBody);
 
         checkStrings(h.firstValue("x-hello").get(), "world");
@@ -231,15 +221,18 @@
         // Do loops asynchronously
 
         CompletableFuture[] responses = new CompletableFuture[LOOPS];
-        final Path source = java.net.http.TestUtil.getAFile(FILESIZE);
+        final Path source = TestUtil.getAFile(FILESIZE);
+        HttpRequest request = HttpRequest.newBuilder(uri)
+                                         .POST(fromFile(tempFile()))
+                                         .build();
         for (int i = 0; i < LOOPS; i++) {
-            responses[i] = client.request(uri)
-                .body(HttpRequest.fromFile(source))
-                .version(HTTP_2)
-                .POST()
-                .responseAsync()
-                .thenCompose(r -> r.bodyAsync(HttpResponse.asFile(tempFile())))
-                .thenApply(path -> compareFiles(path, source));
+            responses[i] = client.sendAsync(request, asFile(tempFile()))
+                //.thenApply(resp -> compareFiles(resp.body(), source));
+                .thenApply(resp -> {
+                    System.out.printf("Resp status %d body size %d\n",
+                                      resp.statusCode(), resp.body().toFile().length());
+                    return compareFiles(resp.body(), source);
+                });
             Thread.sleep(100);
         }
         CompletableFuture.allOf(responses).join();
--- a/jdk/test/java/net/httpclient/http2/ErrorTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/ErrorTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,106 +24,83 @@
 /*
  * @test
  * @bug 8157105
+ * @library /lib/testlibrary server
  * @key intermittent
- * @library /lib/testlibrary
  * @build jdk.testlibrary.SimpleSSLContext
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
  *          java.security.jgss
- * @compile/module=java.httpclient java/net/http/BodyOutputStream.java
- * @compile/module=java.httpclient java/net/http/BodyInputStream.java
- * @compile/module=java.httpclient java/net/http/EchoHandler.java
- * @compile/module=java.httpclient java/net/http/Http2Handler.java
- * @compile/module=java.httpclient java/net/http/Http2TestExchange.java
- * @compile/module=java.httpclient java/net/http/Http2TestServerConnection.java
- * @compile/module=java.httpclient java/net/http/Http2TestServer.java
- * @compile/module=java.httpclient java/net/http/OutgoingPushPromise.java
- * @compile/module=java.httpclient java/net/http/TestUtil.java
- * @run testng/othervm -Djava.net.http.HttpClient.log=ssl,errors ErrorTest
+ * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,errors ErrorTest
  * @summary check exception thrown when bad TLS parameters selected
  */
 
 import java.io.IOException;
 import java.net.URI;
-import java.net.http.EchoHandler;
-import java.net.http.HttpClient;
-import java.net.http.Http2TestServer;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.util.concurrent.ExecutorService;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLParameters;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
 import jdk.testlibrary.SimpleSSLContext;
+import static jdk.incubator.http.HttpClient.Version.HTTP_2;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
 
 import org.testng.annotations.Test;
 
-import static java.net.http.HttpClient.Version.HTTP_2;
-
 /**
  * When selecting an unacceptable cipher suite the TLS handshake will fail.
  * But, the exception that was thrown was not being returned up to application
  * causing hang problems
  */
-@Test
 public class ErrorTest {
-    static int httpsPort;
-    static Http2TestServer httpsServer;
-    static HttpClient client = null;
-    static ExecutorService exec;
-    static SSLContext sslContext;
-
-    static String httpsURIString;
 
-    static HttpClient getClient() {
-        if (client == null) {
-            client = HttpClient.create()
-                .sslContext(sslContext)
-                .sslParameters(new SSLParameters(
-                    new String[]{"TLS_KRB5_WITH_3DES_EDE_CBC_SHA"}))
-                .version(HTTP_2)
-                .build();
-        }
-        return client;
-    }
-
-    static URI getURI() {
-        return URI.create(httpsURIString);
-    }
+    static final String[] CIPHER_SUITES = new String[]{ "TLS_KRB5_WITH_3DES_EDE_CBC_SHA" };
 
     static final String SIMPLE_STRING = "Hello world Goodbye world";
 
-    @Test(timeOut=5000)
-    static void test() throws Exception {
+    //@Test(timeOut=5000)
+    @Test
+    public void test() throws Exception {
+        SSLContext sslContext = (new SimpleSSLContext()).get();
+        ExecutorService exec = Executors.newCachedThreadPool();
+        HttpClient client = HttpClient.newBuilder()
+                                      .executor(exec)
+                                      .sslContext(sslContext)
+                                      .sslParameters(new SSLParameters(CIPHER_SUITES))
+                                      .version(HTTP_2)
+                                      .build();
+
+        Http2TestServer httpsServer = null;
         try {
-            SimpleSSLContext sslct = new SimpleSSLContext();
-            sslContext = sslct.get();
-            client = getClient();
-            exec = client.executorService();
-
-            httpsServer = new Http2TestServer(true, 0, new EchoHandler(),
-                    exec, sslContext);
-
-            httpsPort = httpsServer.getAddress().getPort();
-            httpsURIString = "https://127.0.0.1:" +
-                Integer.toString(httpsPort) + "/bar/";
+            httpsServer = new Http2TestServer(true,
+                                              0,
+                                              exec,
+                                              sslContext);
+            httpsServer.addHandler(new EchoHandler(), "/");
+            int httpsPort = httpsServer.getAddress().getPort();
+            String httpsURIString = "https://127.0.0.1:" + httpsPort + "/bar/";
 
             httpsServer.start();
-            URI uri = getURI();
+            URI uri = URI.create(httpsURIString);
             System.err.println("Request to " + uri);
 
-            HttpClient client = getClient();
-            HttpRequest req = client.request(uri)
-                    .body(HttpRequest.fromString(SIMPLE_STRING))
-                    .POST();
-            HttpResponse response = null;
+            HttpRequest req = HttpRequest.newBuilder(uri)
+                                    .POST(fromString(SIMPLE_STRING))
+                                    .build();
+            HttpResponse response;
             try {
-                response = req.response();
-                throw new RuntimeException("Expected exception");
+                response = client.send(req, discard(null));
+                throw new RuntimeException("Unexpected response: " + response);
             } catch (IOException e) {
-                System.err.println("Expected IOException received " + e);
+                System.err.println("Caught Expected IOException: " + e);
             }
             System.err.println("DONE");
         } finally {
-            httpsServer.stop();
+            if (httpsServer != null )  { httpsServer.stop(); }
             exec.shutdownNow();
         }
     }
--- a/jdk/test/java/net/httpclient/http2/HpackDriver.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/HpackDriver.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,16 +24,16 @@
 /*
  * @test
  * @bug 8153353
- * @modules java.httpclient/sun.net.httpclient.hpack
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
  * @key randomness
- * @compile/module=java.httpclient sun/net/httpclient/hpack/SpecHelper.java
- * @compile/module=java.httpclient sun/net/httpclient/hpack/TestHelper.java
- * @compile/module=java.httpclient sun/net/httpclient/hpack/BuffersTestingKit.java
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.BinaryPrimitivesTest
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.CircularBufferTest
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.DecoderTest
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.EncoderTest
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.HuffmanTest
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.TestHelper
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/hpack/SpecHelper.java
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/hpack/TestHelper.java
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/hpack/BuffersTestingKit.java
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.BinaryPrimitivesTest
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.CircularBufferTest
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.DecoderTest
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.EncoderTest
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.HuffmanTest
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.TestHelper
  */
 public class HpackDriver { }
--- a/jdk/test/java/net/httpclient/http2/HpackDriverHeaderTable.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/HpackDriverHeaderTable.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,12 +24,12 @@
 /*
  * @test
  * @bug 8153353
- * @modules java.httpclient/sun.net.httpclient.hpack
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
  *          jdk.localedata
  * @key randomness
- * @compile/module=java.httpclient sun/net/httpclient/hpack/SpecHelper.java
- * @compile/module=java.httpclient sun/net/httpclient/hpack/TestHelper.java
- * @compile/module=java.httpclient sun/net/httpclient/hpack/BuffersTestingKit.java
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.HeaderTableTest
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/hpack/SpecHelper.java
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/hpack/TestHelper.java
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/hpack/BuffersTestingKit.java
+ * @run testng/othervm jdk.incubator.httpclient/jdk.incubator.http.internal.hpack.HeaderTableTest
  */
 public class HpackDriverHeaderTable { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/NoBody.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,93 @@
+/*
+ * 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 8161157
+ * @library /lib/testlibrary server
+ * @build jdk.testlibrary.SimpleSSLContext
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
+ * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,frames,errors NoBody
+ */
+
+import java.io.IOException;
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import jdk.testlibrary.SimpleSSLContext;
+import static jdk.incubator.http.HttpClient.Version.HTTP_2;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
+
+import org.testng.annotations.Test;
+
+public class NoBody {
+
+    static final String SIMPLE_STRING = "Hello world. Goodbye world";
+
+    @Test(timeOut=60000)
+    public void test() throws Exception {
+        SSLContext sslContext = (new SimpleSSLContext()).get();
+        ExecutorService exec = Executors.newCachedThreadPool();
+        HttpClient client = HttpClient.newBuilder()
+                                      .executor(exec)
+                                      .sslContext(sslContext)
+                                      .version(HTTP_2)
+                                      .build();
+
+        Http2TestServer httpsServer = null;
+        try {
+            httpsServer = new Http2TestServer(true,
+                                              0,
+                                              exec,
+                                              sslContext);
+            httpsServer.addHandler(new NoBodyHandler(), "/");
+
+            int httpsPort = httpsServer.getAddress().getPort();
+            String httpsURIString = "https://127.0.0.1:" + httpsPort + "/bar/";
+
+            httpsServer.start();
+            URI uri = URI.create(httpsURIString);
+            System.err.println("Request to " + uri);
+
+            HttpRequest req = HttpRequest.newBuilder(uri)
+                                         .PUT(fromString(SIMPLE_STRING))
+                                         .build();
+            HttpResponse<String> response = client.send(req, asString());
+            String body = response.body();
+            if (!body.equals(""))
+                throw new RuntimeException("expected empty body");
+            System.err.println("DONE");
+        } finally {
+            if (httpsServer != null )  { httpsServer.stop(); }
+            exec.shutdownNow();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/RedirectTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,170 @@
+/*
+ * 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 8156514
+ * @key intermittent
+ * @library /lib/testlibrary server
+ * @build jdk.testlibrary.SimpleSSLContext
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
+ * @run testng/othervm -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors RedirectTest
+ */
+
+import java.net.*;
+import jdk.incubator.http.*;
+import static jdk.incubator.http.HttpClient.Version.HTTP_2;
+import java.nio.file.*;
+import java.util.concurrent.*;
+import java.util.function.*;
+import java.util.Arrays;
+import java.util.Iterator;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
+
+import org.testng.annotations.Test;
+
+@Test
+public class RedirectTest {
+    static int httpPort, altPort;
+    static Http2TestServer httpServer, altServer;
+    static HttpClient client;
+    static ExecutorService exec;
+
+    static String httpURIString, altURIString1, altURIString2;
+
+    static Supplier<String> sup(String... args) {
+        Iterator<String> i = Arrays.asList(args).iterator();
+        // need to know when to stop calling it.
+        return () -> i.next();
+    }
+
+    static void initialize() throws Exception {
+        try {
+            client = getClient();
+            httpServer = new Http2TestServer(false, 0, exec, null);
+
+            httpPort = httpServer.getAddress().getPort();
+            altServer = new Http2TestServer(false, 0, exec, null);
+            altPort = altServer.getAddress().getPort();
+
+            // urls are accessed in sequence below
+            // first two on different servers. Third on same server
+            // as second. So, the client should use the same http connection
+            httpURIString = "http://127.0.0.1:" + httpPort + "/foo/";
+            altURIString1 = "http://127.0.0.1:" + altPort + "/redir";
+            altURIString2 = "http://127.0.0.1:" + altPort + "/redir/again";
+
+            httpServer.addHandler(new RedirectHandler(sup(altURIString1)), "/foo");
+            altServer.addHandler(new RedirectHandler(sup(altURIString2)), "/redir");
+            altServer.addHandler(new EchoHandler(), "/redir/again");
+
+            httpServer.start();
+            altServer.start();
+        } catch (Throwable e) {
+            System.err.println("Throwing now");
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    @Test(timeOut=3000000)
+    public static void test() throws Exception {
+        try {
+            initialize();
+            simpleTest();
+        } catch (Throwable tt) {
+            System.err.println("tt caught");
+            tt.printStackTrace();
+        } finally {
+            httpServer.stop();
+            altServer.stop();
+            exec.shutdownNow();
+        }
+    }
+
+    static HttpClient getClient() {
+        if (client == null) {
+            exec = Executors.newCachedThreadPool();
+            client = HttpClient.newBuilder()
+                               .executor(exec)
+                               .followRedirects(HttpClient.Redirect.ALWAYS)
+                               .version(HTTP_2)
+                               .build();
+        }
+        return client;
+    }
+
+    static URI getURI() {
+        return URI.create(httpURIString);
+    }
+
+    static void checkStatus(int expected, int found) throws Exception {
+        if (expected != found) {
+            System.err.printf ("Test failed: wrong status code %d/%d\n",
+                expected, found);
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    static void checkStrings(String expected, String found) throws Exception {
+        if (!expected.equals(found)) {
+            System.err.printf ("Test failed: wrong string %s/%s\n",
+                expected, found);
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    static Void compareFiles(Path path1, Path path2) {
+        return TestUtil.compareFiles(path1, path2);
+    }
+
+    static Path tempFile() {
+        return TestUtil.tempFile();
+    }
+
+    static final String SIMPLE_STRING = "Hello world Goodbye world";
+
+    static final int FILESIZE = 64 * 1024 + 200;
+
+    static void simpleTest() throws Exception {
+        URI uri = getURI();
+        System.err.println("Request to " + uri);
+
+        HttpClient client = getClient();
+        HttpRequest req = HttpRequest.newBuilder(uri)
+                                     .POST(fromString(SIMPLE_STRING))
+                                     .build();
+        CompletableFuture<HttpResponse<String>> cf = client.sendAsync(req, asString());
+        HttpResponse<String> response = cf.join();
+
+        checkStatus(200, response.statusCode());
+        String responseBody = response.body();
+        checkStrings(SIMPLE_STRING, responseBody);
+
+        System.err.println("DONE");
+        Thread.sleep (6000);
+    }
+}
--- a/jdk/test/java/net/httpclient/http2/ServerPush.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/ServerPush.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,27 +23,22 @@
 
 /*
  * @test
- * @bug 8087112
- * @library /lib/testlibrary
+ * @bug 8087112 8159814
+ * @library /lib/testlibrary server
  * @build jdk.testlibrary.SimpleSSLContext
- * @modules java.httpclient
- * @compile/module=java.httpclient java/net/http/BodyOutputStream.java
- * @compile/module=java.httpclient java/net/http/BodyInputStream.java
- * @compile/module=java.httpclient java/net/http/PushHandler.java
- * @compile/module=java.httpclient java/net/http/Http2Handler.java
- * @compile/module=java.httpclient java/net/http/Http2TestExchange.java
- * @compile/module=java.httpclient java/net/http/Http2TestServerConnection.java
- * @compile/module=java.httpclient java/net/http/Http2TestServer.java
- * @compile/module=java.httpclient java/net/http/OutgoingPushPromise.java
- * @compile/module=java.httpclient java/net/http/TestUtil.java
- * @run testng/othervm -Djava.net.http.HttpClient.log=requests,responses ServerPush
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
+ * @run testng/othervm -Djdk.httpclient.HttpClient.log=errors,requests,responses ServerPush
  */
 
 import java.io.*;
 import java.net.*;
 import java.nio.file.*;
 import java.nio.file.attribute.*;
-import java.net.http.*;
+import jdk.incubator.http.*;
+import jdk.incubator.http.HttpResponse.MultiProcessor;
+import jdk.incubator.http.HttpResponse.BodyHandler;
 import java.util.*;
 import java.util.concurrent.*;
 import org.testng.annotations.Test;
@@ -53,42 +48,57 @@
     static ExecutorService e = Executors.newCachedThreadPool();
 
     static final int LOOPS = 13;
-    static final int FILE_SIZE = 32 * 1024;
+    static final int FILE_SIZE = 512 * 1024 + 343;
 
     static Path tempFile;
 
     @Test(timeOut=30000)
     public static void test() throws Exception {
         Http2TestServer server = null;
-        Path dir = null;
+        final Path dir = Files.createTempDirectory("serverPush");
         try {
-            server = new Http2TestServer(false, 0,
-                                         new PushHandler(FILE_SIZE, LOOPS));
+            server = new Http2TestServer(false, 0);
+            server.addHandler(new PushHandler(FILE_SIZE, LOOPS), "/");
             tempFile = TestUtil.getAFile(FILE_SIZE);
 
             System.err.println("Server listening on port " + server.getAddress().getPort());
             server.start();
             int port = server.getAddress().getPort();
-            dir = Files.createTempDirectory("serverPush");
+
+            // use multi-level path
+            URI uri = new URI("http://127.0.0.1:" + port + "/foo/a/b/c");
+            HttpRequest request = HttpRequest.newBuilder(uri).GET().build();
 
-            URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/foo");
-            HttpRequest request = HttpRequest.create(uri)
-                    .version(HttpClient.Version.HTTP_2)
-                    .GET();
-
-            CompletableFuture<Map<URI,Path>> cf =
-            request.multiResponseAsync(HttpResponse.multiFile(dir));
-            Map<URI,Path> results = cf.get();
+            CompletableFuture<MultiMapResult<Path>> cf =
+                HttpClient.newBuilder().version(HttpClient.Version.HTTP_2)
+                    .executor(e).build().sendAsync(
+                        request, MultiProcessor.asMap((req) -> {
+                            URI u = req.uri();
+                            Path path = Paths.get(dir.toString(), u.getPath());
+                            try {
+                                Files.createDirectories(path.getParent());
+                            } catch (IOException ee) {
+                                throw new UncheckedIOException(ee);
+                            }
+                            return Optional.of(BodyHandler.asFile(path));
+                        }
+                    ));
+            MultiMapResult<Path> results = cf.get();
 
             //HttpResponse resp = request.response();
             System.err.println(results.size());
-            Set<URI> uris = results.keySet();
-            for (URI u : uris) {
-                Path result = results.get(u);
+            Set<HttpRequest> requests = results.keySet();
+
+            for (HttpRequest r : requests) {
+                URI u = r.uri();
+                Path result = results.get(r).get().body();
                 System.err.printf("%s -> %s\n", u.toString(), result.toString());
                 TestUtil.compareFiles(result, tempFile);
             }
-            System.out.println("TEST OK");
+            if (requests.size() != LOOPS + 1)
+                throw new RuntimeException("some results missing");
+            System.out.println("TEST OK: sleeping for 5 sec");
+            Thread.sleep (5 * 1000);
         } finally {
             e.shutdownNow();
             server.stop();
--- a/jdk/test/java/net/httpclient/http2/TEST.properties	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-bootclasspath.dirs = /java/net/httpclient
--- a/jdk/test/java/net/httpclient/http2/TLSConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/TLSConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -27,24 +27,23 @@
 import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.http.Http2Handler;
-import java.net.http.Http2TestExchange;
-import java.net.http.Http2TestServer;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
 import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSession;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
 /*
  * @test
  * @bug 8150769 8157107
  * @key intermittent
+ * @library server
  * @summary Checks that SSL parameters can be set for HTTP/2 connection
- * @modules java.httpclient
- * @compile/module=java.httpclient java/net/http/Http2Handler.java
- * @compile/module=java.httpclient java/net/http/Http2TestExchange.java
- * @compile/module=java.httpclient java/net/http/Http2TestServer.java
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
  * @run main/othervm TLSConnection
  */
 public class TLSConnection {
@@ -56,7 +55,7 @@
     public static void main(String[] args) throws Exception {
 
         // enable all logging
-        System.setProperty("java.net.http.HttpClient.log", "all,frames:all");
+        System.setProperty("jdk.httpclient.HttpClient.log", "all,frames:all");
 
         // initialize JSSE
         System.setProperty("javax.net.ssl.keyStore", KEYSTORE);
@@ -66,7 +65,8 @@
 
         Handler handler = new Handler();
 
-        try (Http2TestServer server = new Http2TestServer(true, 0, handler)) {
+        try (Http2TestServer server = new Http2TestServer(true, 0)) {
+            server.addHandler(handler, "/");
             server.start();
 
             int port = server.getAddress().getPort();
@@ -158,17 +158,16 @@
     }
 
     private static void connect(String uriString, SSLParameters sslParameters)
-            throws URISyntaxException, IOException, InterruptedException {
-
-        String body = HttpClient.create()
-                .sslParameters(sslParameters)
-                .version(HttpClient.Version.HTTP_2)
-                .build()
-                .request(new URI(uriString))
-                .body(HttpRequest.fromString("body"))
-                .GET()
-                .response()
-                .body(HttpResponse.asString());
+        throws URISyntaxException, IOException, InterruptedException
+    {
+        HttpClient client = HttpClient.newBuilder()
+                                      .sslParameters(sslParameters)
+                                      .version(HttpClient.Version.HTTP_2)
+                                      .build();
+        HttpRequest request = HttpRequest.newBuilder(new URI(uriString))
+                                         .POST(fromString("body"))
+                                         .build();
+        String body = client.send(request, asString()).body();
 
         System.out.println("Response: " + body);
     }
--- a/jdk/test/java/net/httpclient/http2/Timeout.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/http2/Timeout.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,14 +24,18 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.net.http.HttpTimeoutException;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
+import jdk.incubator.http.HttpTimeoutException;
+import java.time.Duration;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.CompletionException;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSocket;
+import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
 /*
  * @test
@@ -51,6 +55,11 @@
     private static volatile boolean ready = false;
 
     public static void main(String[] args) throws Exception {
+        test(false);
+        test(true);
+    }
+
+    public static void test(boolean async) throws Exception {
         System.setProperty("javax.net.ssl.keyStore", KEYSTORE);
         System.setProperty("javax.net.ssl.keyStorePassword", PASSWORD);
         System.setProperty("javax.net.ssl.trustStore", KEYSTORE);
@@ -89,26 +98,52 @@
             } while (!ready);
 
             String uri = "https://localhost:" + ssocket.getLocalPort();
-            connect(uri);
+            if (async) {
+                System.out.println(uri + ": Trying to connect asynchronously");
+                connectAsync(uri);
+            } else {
+                System.out.println(uri + ": Trying to connect synchronously");
+                connect(uri);
+            }
         }
     }
 
     private static void connect(String server) throws Exception {
         try {
-            HttpClient.create()
-                    .version(HttpClient.Version.HTTP_2)
-                    .build()
-                    .request(new URI(server))
-                    .timeout(TimeUnit.MILLISECONDS, TIMEOUT)
-                    .body(HttpRequest.fromString("body"))
-                    .GET()
-                    .response()
-                    .body(HttpResponse.asString());
-
+            HttpClient client = HttpClient.newBuilder()
+                                          .version(HttpClient.Version.HTTP_2)
+                                          .build();
+            HttpRequest request = HttpRequest.newBuilder(new URI(server))
+                                             .timeout(Duration.ofMillis(TIMEOUT))
+                                             .POST(fromString("body"))
+                                             .build();
+            HttpResponse<String> response = client.send(request, asString());
+            System.out.println("Received unexpected reply: " + response.statusCode());
             throw new RuntimeException("unexpected successful connection");
         } catch (HttpTimeoutException e) {
             System.out.println("expected exception: " + e);
         }
     }
 
+    private static void connectAsync(String server) throws Exception {
+        try {
+            HttpClient client = HttpClient.newBuilder()
+                    .version(HttpClient.Version.HTTP_2)
+                    .build();
+            HttpRequest request = HttpRequest.newBuilder(new URI(server))
+                    .timeout(Duration.ofMillis(TIMEOUT))
+                    .POST(fromString("body"))
+                    .build();
+            HttpResponse<String> response = client.sendAsync(request, asString()).join();
+            System.out.println("Received unexpected reply: " + response.statusCode());
+            throw new RuntimeException("unexpected successful connection");
+        } catch (CompletionException e) {
+            if (e.getCause() instanceof HttpTimeoutException) {
+                System.out.println("expected exception: " + e.getCause());
+            } else {
+                throw new RuntimeException("Unexpected exception received: " + e.getCause(), e);
+            }
+        }
+    }
+
 }
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/BodyInputStream.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-package java.net.http;
-
-import java.io.*;
-import java.nio.ByteBuffer;
-
-/**
- * InputStream reads frames off stream q and supplies read demand from any
- * DataFrames it finds. Window updates are sent back on the connections send
- * q.
- */
-class BodyInputStream extends InputStream {
-
-    final Queue<Http2Frame> q;
-    final int streamid;
-    boolean closed;
-    boolean eof;
-    final Http2TestServerConnection conn;
-
-    @SuppressWarnings({"rawtypes","unchecked"})
-    BodyInputStream(Queue q, int streamid, Http2TestServerConnection conn) {
-        this.q = q;
-        this.streamid = streamid;
-        this.conn = conn;
-    }
-
-    DataFrame df;
-    ByteBuffer[] buffers;
-    ByteBuffer buffer;
-    int nextIndex = -1;
-
-    private DataFrame getData() throws IOException {
-        if (eof) {
-            return null;
-        }
-        Http2Frame frame;
-        do {
-            frame = q.take();
-            if (frame.type() == ResetFrame.TYPE) {
-                conn.handleStreamReset((ResetFrame) frame); // throws IOException
-            }
-            // ignoring others for now Wupdates handled elsewhere
-            if (frame.type() != DataFrame.TYPE) {
-                System.out.println("Ignoring " + frame.toString() + " CHECK THIS");
-            }
-        } while (frame.type() != DataFrame.TYPE);
-        df = (DataFrame) frame;
-        int len = df.getDataLength();
-        eof = frame.getFlag(DataFrame.END_STREAM);
-        // acknowledge
-        conn.sendWindowUpdates(len, streamid);
-        return (DataFrame) frame;
-    }
-
-    // null return means EOF
-    private ByteBuffer getBuffer() throws IOException {
-        if (buffer == null || !buffer.hasRemaining()) {
-            if (nextIndex == -1 || nextIndex == buffers.length) {
-                DataFrame df = getData();
-                if (df == null) {
-                    return null;
-                }
-                int len = df.getDataLength();
-                if ((len == 0) && eof) {
-                    return null;
-                }
-                buffers = df.getData();
-                nextIndex = 0;
-            }
-            buffer = buffers[nextIndex++];
-        }
-        return buffer;
-    }
-
-    @Override
-    public int read(byte[] buf, int offset, int length) throws IOException {
-        if (closed) {
-            throw new IOException("closed");
-        }
-        ByteBuffer b = getBuffer();
-        if (b == null) {
-            return -1;
-        }
-        int remaining = b.remaining();
-        if (remaining < length) {
-            length = remaining;
-        }
-        b.get(buf, offset, length);
-        return length;
-    }
-
-    byte[] one = new byte[1];
-
-    @Override
-    public int read() throws IOException {
-        int c = read(one, 0, 1);
-        if (c == -1) {
-            return -1;
-        }
-        return one[0];
-    }
-
-    @Override
-    public void close() {
-        // TODO reset this stream
-        closed = true;
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/BodyOutputStream.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-package java.net.http;
-
-import java.io.*;
-import java.nio.ByteBuffer;
-
-/**
- * OutputStream. Incoming window updates handled by the main connection
- * reader thread.
- */
-@SuppressWarnings({"rawtypes","unchecked"})
-class BodyOutputStream extends OutputStream {
-    final static byte[] EMPTY_BARRAY = new byte[0];
-
-    final int streamid;
-    int window;
-    boolean closed;
-    boolean goodToGo = false; // not allowed to send until headers sent
-    final Http2TestServerConnection conn;
-    final Queue outputQ;
-
-    BodyOutputStream(int streamid, int initialWindow, Http2TestServerConnection conn) {
-        this.window = initialWindow;
-        this.streamid = streamid;
-        this.conn = conn;
-        this.outputQ = conn.outputQ;
-        conn.registerStreamWindowUpdater(streamid, this::updateWindow);
-    }
-
-    // called from connection reader thread as all incoming window
-    // updates are handled there.
-    synchronized void updateWindow(int update) {
-        window += update;
-        notifyAll();
-    }
-
-    void waitForWindow(int demand) throws InterruptedException {
-        // first wait for the connection window
-        conn.obtainConnectionWindow(demand);
-        // now wait for the stream window
-        synchronized (this) {
-            while (demand > 0) {
-                int n = Math.min(demand, window);
-                demand -= n;
-                window -= n;
-                if (demand > 0) {
-                    wait();
-                }
-            }
-        }
-    }
-
-    void goodToGo() {
-        goodToGo = true;
-    }
-
-    @Override
-    public void write(byte[] buf, int offset, int len) throws IOException {
-        if (closed) {
-            throw new IOException("closed");
-        }
-
-        if (!goodToGo) {
-            throw new IllegalStateException("sendResponseHeaders must be called first");
-        }
-        try {
-            waitForWindow(len);
-            send(buf, offset, len, 0);
-        } catch (InterruptedException ex) {
-            throw new IOException(ex);
-        }
-    }
-
-    private void send(byte[] buf, int offset, int len, int flags) throws IOException {
-        ByteBuffer buffer = ByteBuffer.allocate(len);
-        buffer.put(buf, offset, len);
-        buffer.flip();
-        DataFrame df = new DataFrame();
-        assert streamid != 0;
-        df.streamid(streamid);
-        df.setFlags(flags);
-        df.setData(buffer);
-        outputQ.put(df);
-    }
-
-    byte[] one = new byte[1];
-
-    @Override
-    public void write(int b) throws IOException {
-        one[0] = (byte) b;
-        write(one, 0, 1);
-    }
-
-    @Override
-    public void close() {
-        if (closed) {
-            return;
-        }
-        closed = true;
-        try {
-            send(EMPTY_BARRAY, 0, 0, DataFrame.END_STREAM);
-        } catch (IOException ex) {
-            System.err.println("TestServer: OutputStream.close exception: " + ex);
-            ex.printStackTrace();
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/EchoHandler.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net.http;
-
-import java.util.*;
-import java.util.concurrent.*;
-import java.io.*;
-import java.net.*;
-
-public class EchoHandler implements Http2Handler {
-    public EchoHandler() {}
-
-    @Override
-    public void handle(Http2TestExchange t)
-            throws IOException {
-        try {
-            System.err.println("EchoHandler received request to " + t.getRequestURI());
-            InputStream is = t.getRequestBody();
-            HttpHeadersImpl map = t.getRequestHeaders();
-            HttpHeadersImpl map1 = t.getResponseHeaders();
-            map1.addHeader("X-Hello", "world");
-            map1.addHeader("X-Bye", "universe");
-            String fixedrequest = map.firstValue("XFixed").orElse(null);
-            File outfile = File.createTempFile("foo", "bar");
-            FileOutputStream fos = new FileOutputStream(outfile);
-            int count = (int) is.transferTo(fos);
-            System.err.printf("EchoHandler read %d bytes\n", count);
-            is.close();
-            fos.close();
-            InputStream is1 = new FileInputStream(outfile);
-            OutputStream os = null;
-            // return the number of bytes received (no echo)
-            String summary = map.firstValue("XSummary").orElse(null);
-            if (fixedrequest != null && summary == null) {
-                t.sendResponseHeaders(200, count);
-                os = t.getResponseBody();
-                is1.transferTo(os);
-            } else {
-                t.sendResponseHeaders(200, 0);
-                os = t.getResponseBody();
-                int count1 = (int)is1.transferTo(os);
-                System.err.printf("EchoHandler wrote %d bytes\n", count1);
-
-                if (summary != null) {
-                    String s = Integer.toString(count);
-                    os.write(s.getBytes());
-                }
-            }
-            outfile.delete();
-            os.close();
-            is1.close();
-        } catch (Throwable e) {
-            e.printStackTrace();
-            throw new IOException(e);
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2Handler.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-package java.net.http;
-
-import java.io.IOException;
-
-/**
- * A handler which is invoked to process HTTP exchanges. Each
- * HTTP exchange is handled by one of these handlers.
- */
-public interface Http2Handler {
-    /**
-     * Handle the given request and generate an appropriate response.
-     * @param exchange the exchange containing the request from the
-     *      client and used to send the response
-     * @throws NullPointerException if exchange is <code>null</code>
-     */
-    public abstract void handle (Http2TestExchange exchange) throws IOException;
-}
-
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestExchange.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-package java.net.http;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.net.InetSocketAddress;
-import javax.net.ssl.SSLSession;
-
-public class Http2TestExchange {
-
-    final HttpHeadersImpl reqheaders;
-    final HttpHeadersImpl rspheaders;
-    final URI uri;
-    final String method;
-    final InputStream is;
-    final BodyOutputStream os;
-    final SSLSession sslSession;
-    final int streamid;
-    final boolean pushAllowed;
-    final Http2TestServerConnection conn;
-    final Http2TestServer server;
-
-    int responseCode = -1;
-    long responseLength;
-
-    Http2TestExchange(int streamid, String method, HttpHeadersImpl reqheaders,
-            HttpHeadersImpl rspheaders, URI uri, InputStream is,
-            SSLSession sslSession,
-            BodyOutputStream os, Http2TestServerConnection conn, boolean pushAllowed) {
-        this.reqheaders = reqheaders;
-        this.rspheaders = rspheaders;
-        this.uri = uri;
-        this.method = method;
-        this.is = is;
-        this.streamid = streamid;
-        this.os = os;
-        this.sslSession = sslSession;
-        this.pushAllowed = pushAllowed;
-        this.conn = conn;
-        this.server = conn.server;
-    }
-
-    public HttpHeadersImpl getRequestHeaders() {
-        return reqheaders;
-    }
-
-    public HttpHeadersImpl getResponseHeaders() {
-        return rspheaders;
-    }
-
-    public URI getRequestURI() {
-        return uri;
-    }
-
-    public String getRequestMethod() {
-        return method;
-    }
-
-    public SSLSession getSSLSession() {
-        return sslSession;
-    }
-
-    public void close() {
-        try {
-            is.close();
-            os.close();
-        } catch (IOException e) {
-            System.err.println("TestServer: HttpExchange.close exception: " + e);
-            e.printStackTrace();
-        }
-    }
-
-    public InputStream getRequestBody() {
-        return is;
-    }
-
-    public OutputStream getResponseBody() {
-        return os;
-    }
-
-    public void sendResponseHeaders(int rCode, long responseLength) throws IOException {
-        this.responseLength = responseLength;
-        if (responseLength > 0 || responseLength < 0) {
-                long clen = responseLength > 0 ? responseLength : 0;
-            rspheaders.setHeader("Content-length", Long.toString(clen));
-        }
-
-        rspheaders.setHeader(":status", Integer.toString(rCode));
-
-        Http2TestServerConnection.ResponseHeaders response
-                = new Http2TestServerConnection.ResponseHeaders(rspheaders);
-        response.streamid(streamid);
-        response.setFlag(HeaderFrame.END_HEADERS);
-        conn.outputQ.put(response);
-        os.goodToGo();
-        System.err.println("Sent response headers " + rCode);
-    }
-
-    public InetSocketAddress getRemoteAddress() {
-        return (InetSocketAddress) conn.socket.getRemoteSocketAddress();
-    }
-
-    public int getResponseCode() {
-        return responseCode;
-    }
-
-    public InetSocketAddress getLocalAddress() {
-        return server.getAddress();
-    }
-
-    public String getProtocol() {
-        return "HTTP/2";
-    }
-
-    public boolean serverPushAllowed() {
-        return pushAllowed;
-    }
-
-    public void serverPush(URI uri, HttpHeadersImpl headers, InputStream content) {
-        OutgoingPushPromise pp = new OutgoingPushPromise(
-                streamid, uri, headers, content);
-        headers.setHeader(":method", "GET");
-        headers.setHeader(":scheme", uri.getScheme());
-        headers.setHeader(":authority", uri.getAuthority());
-        headers.setHeader(":path", uri.getPath());
-        try {
-            conn.outputQ.put(pp);
-            // writeLoop will spin up thread to read the InputStream
-        } catch (IOException ex) {
-            System.err.println("TestServer: pushPromise exception: " + ex);
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net.http;
-
-import java.io.IOException;
-import java.net.*;
-import java.util.HashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import javax.net.ServerSocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
-
-/**
- * Waits for incoming TCP connections from a client and establishes
- * a HTTP2 connection. Two threads are created per connection. One for reading
- * and one for writing. Incoming requests are dispatched to the supplied
- * Http2Handler on additional threads. All threads
- * obtained from the supplied ExecutorService.
- */
-public class Http2TestServer implements AutoCloseable {
-    final ServerSocket server;
-    boolean secure;
-    SettingsFrame serverSettings, clientSettings;
-    final ExecutorService exec;
-    volatile boolean stopping = false;
-    final Http2Handler handler;
-    final SSLContext sslContext;
-    final HashMap<InetSocketAddress,Http2TestServerConnection> connections;
-
-    private static ThreadFactory defaultThreadFac =
-        (Runnable r) -> {
-            Thread t = new Thread(r);
-            t.setName("Test-server-pool");
-            return t;
-        };
-
-
-    private static ExecutorService getDefaultExecutor() {
-        return Executors.newCachedThreadPool(defaultThreadFac);
-    }
-
-    public Http2TestServer(boolean secure, int port, Http2Handler handler) throws Exception {
-        this(secure, port, handler, getDefaultExecutor(), null);
-    }
-
-    public InetSocketAddress getAddress() {
-        return (InetSocketAddress)server.getLocalSocketAddress();
-    }
-
-    /**
-     * Create a Http2Server listening on the given port. Currently needs
-     * to know in advance whether incoming connections are plain TCP "h2c"
-     * or TLS "h2"/
-     *
-     * @param secure https or http
-     * @param port listen port
-     * @param handler the handler which receives incoming requests
-     * @param exec executor service (cached thread pool is used if null)
-     * @param context the SSLContext used when secure is true
-     * @throws Exception
-     */
-    public Http2TestServer(boolean secure, int port, Http2Handler handler,
-            ExecutorService exec, SSLContext context) throws Exception {
-        if (secure) {
-            server = initSecure(port);
-        } else {
-            server = initPlaintext(port);
-        }
-        this.secure = secure;
-        this.exec = exec == null ? getDefaultExecutor() : exec;
-        this.handler = handler;
-        this.sslContext = context;
-        this.connections = new HashMap<>();
-    }
-
-    final ServerSocket initPlaintext(int port) throws Exception {
-        return new ServerSocket(port);
-    }
-
-    public void stop() {
-        // TODO: clean shutdown GoAway
-        stopping = true;
-        for (Http2TestServerConnection connection : connections.values()) {
-            connection.close();
-        }
-        try {
-            server.close();
-        } catch (IOException e) {}
-        exec.shutdownNow();
-    }
-
-
-    final ServerSocket initSecure(int port) throws Exception {
-        ServerSocketFactory fac;
-        if (sslContext != null) {
-            fac = sslContext.getServerSocketFactory();
-        } else {
-            fac = SSLServerSocketFactory.getDefault();
-        }
-        SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(port);
-        SSLParameters sslp = se.getSSLParameters();
-        sslp.setApplicationProtocols(new String[]{"h2"});
-        se.setSSLParameters(sslp);
-        se.setEnabledCipherSuites(se.getSupportedCipherSuites());
-        se.setEnabledProtocols(se.getSupportedProtocols());
-        // other initialisation here
-        return se;
-    }
-
-    /**
-     * Start thread which waits for incoming connections.
-     *
-     * @throws Exception
-     */
-    public void start() {
-        exec.submit(() -> {
-            try {
-                while (!stopping) {
-                    Socket socket = server.accept();
-                    InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress();
-                    Http2TestServerConnection c = new Http2TestServerConnection(this, socket);
-                    connections.put(addr, c);
-                    c.run();
-                }
-            } catch (Throwable e) {
-                if (!stopping) {
-                    System.err.println("TestServer: start exception: " + e);
-                    e.printStackTrace();
-                }
-            }
-        });
-    }
-
-    @Override
-    public void close() throws Exception {
-        stop();
-    }
-
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServerConnection.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,739 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net.http;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.net.URI;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import java.net.URISyntaxException;
-import static java.net.http.SettingsFrame.HEADER_TABLE_SIZE;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.concurrent.ExecutorService;
-import java.util.function.Consumer;
-import sun.net.httpclient.hpack.Decoder;
-import sun.net.httpclient.hpack.DecodingCallback;
-import sun.net.httpclient.hpack.Encoder;
-
-/**
- * Represents one HTTP2 connection, either plaintext upgraded from HTTP/1.1
- * or HTTPS opened using "h2" ALPN.
- */
-public class Http2TestServerConnection {
-    final Http2TestServer server;
-    @SuppressWarnings({"rawtypes","unchecked"})
-    final Map<Integer, Queue> streams; // input q per stream
-    final Queue<Http2Frame> outputQ;
-    int nextstream;
-    final Socket socket;
-    final InputStream is;
-    final OutputStream os;
-    Encoder hpackOut;
-    Decoder hpackIn;
-    SettingsFrame clientSettings, serverSettings;
-    final ExecutorService exec;
-    final boolean secure;
-    final Http2Handler handler;
-    volatile boolean stopping;
-    int nextPushStreamId = 2;
-
-    final static ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
-    final static byte[] EMPTY_BARRAY = new byte[0];
-
-    final static byte[] clientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes();
-
-    Http2TestServerConnection(Http2TestServer server, Socket socket) throws IOException {
-        System.err.println("New connection from " + socket);
-        this.server = server;
-        this.streams = Collections.synchronizedMap(new HashMap<>());
-        this.outputQ = new Queue<>();
-        this.socket = socket;
-        this.clientSettings = server.clientSettings;
-        this.serverSettings = server.serverSettings;
-        this.exec = server.exec;
-        this.secure = server.secure;
-        this.handler = server.handler;
-        is = new BufferedInputStream(socket.getInputStream());
-        os = new BufferedOutputStream(socket.getOutputStream());
-    }
-
-    void close() {
-        streams.forEach((i, q) -> {
-            q.close();
-        });
-        stopping = true;
-        try {
-            socket.close();
-            // TODO: put a reset on each stream
-        } catch (IOException e) {
-        }
-    }
-
-    private void readPreface() throws IOException {
-        int len = clientPreface.length;
-        byte[] bytes = new byte[len];
-        is.readNBytes(bytes, 0, len);
-        if (Arrays.compare(clientPreface, bytes) != 0) {
-            throw new IOException("Invalid preface: " + new String(bytes, 0, len));
-        }
-    }
-
-    String doUpgrade() throws IOException {
-        String upgrade = readHttp1Request();
-        String h2c = getHeader(upgrade, "Upgrade");
-        if (h2c == null || !h2c.equals("h2c")) {
-            throw new IOException("Bad upgrade 1 " + h2c);
-        }
-
-        sendHttp1Response(101, "Switching Protocols", "Connection", "Upgrade",
-                "Upgrade", "h2c");
-
-        sendSettingsFrame();
-        readPreface();
-
-        String clientSettingsString = getHeader(upgrade, "HTTP2-Settings");
-        clientSettings = getSettingsFromString(clientSettingsString);
-
-        return upgrade;
-    }
-
-    /**
-     * Client settings payload provided in base64 HTTP1 header. Decode it
-     * and add a header so we can interpret it.
-     *
-     * @param s
-     * @return
-     * @throws IOException
-     */
-    private SettingsFrame getSettingsFromString(String s) throws IOException {
-        Base64.Decoder decoder = Base64.getUrlDecoder();
-        byte[] payload = decoder.decode(s);
-        ByteBuffer bb1 = ByteBuffer.wrap(payload);
-        // simulate header of Settings Frame
-        ByteBuffer bb0 = ByteBuffer.wrap(
-                new byte[] {0, 0, (byte)payload.length, 4, 0, 0, 0, 0, 0});
-        ByteBufferConsumer bbc = new ByteBufferConsumer(
-                new LinkedList<ByteBuffer>(List.of(bb0, bb1)),
-                this::getBuffer);
-        Http2Frame frame = Http2Frame.readIncoming(bbc);
-        if (!(frame instanceof SettingsFrame))
-            throw new IOException("Expected SettingsFrame");
-        return (SettingsFrame)frame;
-    }
-
-    void run() throws Exception {
-        String upgrade = null;
-        if (!secure) {
-            upgrade = doUpgrade();
-        } else {
-            readPreface();
-            sendSettingsFrame(true);
-            clientSettings = (SettingsFrame) readFrame();
-            nextstream = 1;
-        }
-
-        hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
-        hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE));
-
-        exec.submit(() -> {
-            readLoop();
-        });
-        exec.submit(() -> {
-            writeLoop();
-        });
-        if (!secure) {
-            createPrimordialStream(upgrade);
-            nextstream = 3;
-        }
-    }
-
-    static class BufferPool implements BufferHandler {
-
-        public void setMinBufferSize(int size) {
-        }
-
-        public ByteBuffer getBuffer(int size) {
-            if (size == -1)
-                size = 32 * 1024;
-            return ByteBuffer.allocate(size);
-        }
-
-        public void returnBuffer(ByteBuffer buffer) {
-        }
-    }
-
-    static BufferPool bufferpool = new BufferPool();
-
-    private void writeFrame(Http2Frame frame) throws IOException {
-        ByteBufferGenerator bg = new ByteBufferGenerator(bufferpool);
-        frame.computeLength();
-        System.err.println("Writing frame " + frame.toString());
-        frame.writeOutgoing(bg);
-        ByteBuffer[] bufs = bg.getBufferArray();
-        int c = 0;
-        for (ByteBuffer buf : bufs) {
-            byte[] ba = buf.array();
-            int start = buf.arrayOffset() + buf.position();
-            c += buf.remaining();
-            os.write(ba, start, buf.remaining());
-        }
-        os.flush();
-        System.err.printf("wrote %d bytes\n", c);
-    }
-
-    void handleStreamReset(ResetFrame resetFrame) throws IOException {
-        // TODO: cleanup
-        throw new IOException("Stream reset");
-    }
-
-    private void handleCommonFrame(Http2Frame f) throws IOException {
-        if (f instanceof SettingsFrame) {
-            serverSettings = (SettingsFrame) f;
-            if (serverSettings.getFlag(SettingsFrame.ACK)) // ignore
-            {
-                return;
-            }
-            // otherwise acknowledge it
-            SettingsFrame frame = new SettingsFrame();
-            frame.setFlag(SettingsFrame.ACK);
-            frame.streamid(0);
-            outputQ.put(frame);
-            return;
-        }
-        System.err.println("Received ---> " + f.toString());
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    void sendWindowUpdates(int len, int streamid) throws IOException {
-        if (len == 0)
-            return;
-        WindowUpdateFrame wup = new WindowUpdateFrame();
-        wup.streamid(streamid);
-        wup.setUpdate(len);
-        outputQ.put(wup);
-        wup = new WindowUpdateFrame();
-        wup.streamid(0);
-        wup.setUpdate(len);
-        outputQ.put(wup);
-    }
-
-    HttpHeadersImpl decodeHeaders(List<HeaderFrame> frames) {
-        HttpHeadersImpl headers = new HttpHeadersImpl();
-
-        DecodingCallback cb = (name, value) -> {
-            headers.addHeader(name.toString(), value.toString());
-        };
-
-        for (HeaderFrame frame : frames) {
-            ByteBuffer[] buffers = frame.getHeaderBlock();
-            for (ByteBuffer buffer : buffers) {
-                hpackIn.decode(buffer, false, cb);
-            }
-        }
-        hpackIn.decode(EMPTY_BUFFER, true, cb);
-        return headers;
-    }
-
-    String getRequestLine(String request) {
-        int eol = request.indexOf(CRLF);
-        return request.substring(0, eol);
-    }
-
-    // First stream (1) comes from a plaintext HTTP/1.1 request
-    @SuppressWarnings({"rawtypes","unchecked"})
-    void createPrimordialStream(String request) throws IOException {
-        HttpHeadersImpl headers = new HttpHeadersImpl();
-        String requestLine = getRequestLine(request);
-        String[] tokens = requestLine.split(" ");
-        if (!tokens[2].equals("HTTP/1.1")) {
-            throw new IOException("bad request line");
-        }
-        URI uri = null;
-        try {
-            uri = new URI(tokens[1]);
-        } catch (URISyntaxException e) {
-            throw new IOException(e);
-        }
-        String host = getHeader(request, "Host");
-        if (host == null) {
-            throw new IOException("missing Host");
-        }
-
-        headers.setHeader(":method", tokens[0]);
-        headers.setHeader(":scheme", "http"); // always in this case
-        headers.setHeader(":authority", host);
-        headers.setHeader(":path", uri.getPath());
-        Queue q = new Queue();
-        String body = getRequestBody(request);
-        headers.setHeader("Content-length", Integer.toString(body.length()));
-
-        addRequestBodyToQueue(body, q);
-        streams.put(1, q);
-        exec.submit(() -> {
-            handleRequest(headers, q, 1);
-        });
-    }
-
-    // all other streams created here
-    @SuppressWarnings({"rawtypes","unchecked"})
-    void createStream(HeaderFrame frame) throws IOException {
-        List<HeaderFrame> frames = new LinkedList<>();
-        frames.add(frame);
-        int streamid = frame.streamid();
-        if (streamid != nextstream) {
-            throw new IOException("unexpected stream id");
-        }
-        nextstream += 2;
-
-        while (!frame.getFlag(HeaderFrame.END_HEADERS)) {
-            Http2Frame f = readFrame();
-            if (!(f instanceof HeaderFrame)) {
-                handleCommonFrame(f); // should only be error frames
-            } else {
-                frame = (HeaderFrame) f;
-                frames.add(frame);
-            }
-        }
-        HttpHeadersImpl headers = decodeHeaders(frames);
-        Queue q = new Queue();
-        streams.put(streamid, q);
-        exec.submit(() -> {
-            handleRequest(headers, q, streamid);
-        });
-    }
-
-    // runs in own thread. Handles request from start to finish. Incoming frames
-    // for this stream/request delivered on Q
-
-    @SuppressWarnings({"rawtypes","unchecked"})
-    void handleRequest(HttpHeadersImpl headers, Queue queue, int streamid) {
-        String method = headers.firstValue(":method").orElse("");
-        System.out.println("method = " + method);
-        String path = headers.firstValue(":path").orElse("");
-        System.out.println("path = " + path);
-        String scheme = headers.firstValue(":scheme").orElse("");
-        System.out.println("scheme = " + scheme);
-        String authority = headers.firstValue(":authority").orElse("");
-        System.out.println("authority = " + authority);
-        HttpHeadersImpl rspheaders = new HttpHeadersImpl();
-        int winsize = clientSettings.getParameter(
-                        SettingsFrame.INITIAL_WINDOW_SIZE);
-        System.err.println ("Stream window size = " + winsize);
-        try (
-            BodyInputStream bis = new BodyInputStream(queue, streamid, this);
-            BodyOutputStream bos = new BodyOutputStream(streamid, winsize, this);
-        )
-        {
-            String us = scheme + "://" + authority + path;
-            URI uri = new URI(us);
-            boolean pushAllowed = clientSettings.getParameter(SettingsFrame.ENABLE_PUSH) == 1;
-            Http2TestExchange exchange = new Http2TestExchange(streamid, method,
-                    headers, rspheaders, uri, bis, getSSLSession(),
-                    bos, this, pushAllowed);
-
-            // give to user
-            handler.handle(exchange);
-
-            // everything happens in the exchange from here. Hopefully will
-            // return though.
-        } catch (Throwable e) {
-            System.err.println("TestServer: handleRequest exception: " + e);
-            e.printStackTrace();
-        }
-    }
-
-    private SSLSession getSSLSession() {
-        if (! (socket instanceof SSLSocket))
-            return null;
-        SSLSocket ssl = (SSLSocket)socket;
-        return ssl.getSession();
-    }
-    // Runs in own thread
-
-    @SuppressWarnings({"rawtypes","unchecked"})
-    void readLoop() {
-        try {
-            while (!stopping) {
-                Http2Frame frame = readFrame();
-                int stream = frame.streamid();
-                if (stream == 0) {
-                    if (frame.type() == WindowUpdateFrame.TYPE) {
-                        WindowUpdateFrame wup = (WindowUpdateFrame) frame;
-                        updateConnectionWindow(wup.getUpdate());
-                    } else {
-                        // other common frame types
-                        handleCommonFrame(frame);
-                    }
-                } else {
-                    Queue q = streams.get(stream);
-                    if (frame.type() == HeadersFrame.TYPE) {
-                        if (q != null) {
-                            System.err.println("HEADERS frame for existing stream! Error.");
-                            // TODO: close connection
-                            continue;
-                        } else {
-                            createStream((HeadersFrame) frame);
-                        }
-                    } else {
-                        if (q == null) {
-                            System.err.printf("Non Headers frame received with"+
-                                " non existing stream (%d) ", frame.streamid());
-                            System.err.println(frame);
-                            continue;
-                        }
-                        if (frame.type() == WindowUpdateFrame.TYPE) {
-                            WindowUpdateFrame wup = (WindowUpdateFrame) frame;
-                            synchronized (updaters) {
-                                Consumer<Integer> r = updaters.get(stream);
-                                r.accept(wup.getUpdate());
-                            }
-                        } else {
-                            q.put(frame);
-                        }
-                    }
-                }
-            }
-        } catch (Throwable e) {
-            close();
-            if (!stopping) {
-                System.err.println("Http server reader thread shutdown");
-                e.printStackTrace();
-            }
-        }
-    }
-
-    // set streamid outside plus other specific fields
-    void encodeHeaders(HttpHeadersImpl headers, HeaderFrame out) {
-        List<ByteBuffer> buffers = new LinkedList<>();
-
-        ByteBuffer buf = getBuffer();
-        boolean encoded;
-        for (Map.Entry<String, List<String>> entry : headers.map().entrySet()) {
-            List<String> values = entry.getValue();
-            String key = entry.getKey().toLowerCase();
-            for (String value : values) {
-                do {
-                    hpackOut.header(key, value);
-                    encoded = hpackOut.encode(buf);
-                    if (!encoded) {
-                        buf.flip();
-                        buffers.add(buf);
-                        buf = getBuffer();
-                    }
-                } while (!encoded);
-            }
-        }
-        buf.flip();
-        buffers.add(buf);
-        out.setFlags(HeaderFrame.END_HEADERS);
-        out.setHeaderBlock(buffers.toArray(bbarray));
-    }
-
-    static void closeIgnore(Closeable c) {
-        try {
-            c.close();
-        } catch (IOException e) {}
-    }
-
-    // Runs in own thread
-    void writeLoop() {
-        try {
-            while (!stopping) {
-                Http2Frame frame = outputQ.take();
-                if (frame instanceof ResponseHeaders) {
-                    ResponseHeaders rh = (ResponseHeaders)frame;
-                    HeadersFrame hf = new HeadersFrame();
-                    encodeHeaders(rh.headers, hf);
-                    hf.streamid(rh.streamid());
-                    writeFrame(hf);
-                } else if (frame instanceof OutgoingPushPromise) {
-                    handlePush((OutgoingPushPromise)frame);
-                } else
-                    writeFrame(frame);
-            }
-            System.err.println("Connection writer stopping");
-        } catch (Throwable e) {
-            e.printStackTrace();
-            /*close();
-            if (!stopping) {
-                e.printStackTrace();
-                System.err.println("TestServer: writeLoop exception: " + e);
-            }*/
-        }
-    }
-
-    private void handlePush(OutgoingPushPromise op) throws IOException {
-        PushPromiseFrame pp = new PushPromiseFrame();
-        encodeHeaders(op.headers, pp);
-        int promisedStreamid = nextPushStreamId;
-        nextPushStreamId += 2;
-        pp.streamid(op.parentStream);
-        pp.setPromisedStream(promisedStreamid);
-        writeFrame(pp);
-        final InputStream ii = op.is;
-        final BodyOutputStream oo = new BodyOutputStream(
-                promisedStreamid,
-                clientSettings.getParameter(
-                        SettingsFrame.INITIAL_WINDOW_SIZE), this);
-        oo.goodToGo();
-        exec.submit(() -> {
-            try {
-                ResponseHeaders oh = getPushResponse(promisedStreamid);
-                outputQ.put(oh);
-                ii.transferTo(oo);
-            } catch (Throwable ex) {
-                System.err.printf("TestServer: pushing response error: %s\n",
-                        ex.toString());
-            } finally {
-                closeIgnore(ii);
-                closeIgnore(oo);
-            }
-        });
-
-    }
-
-    // returns a minimal response with status 200
-    // that is the response to the push promise just sent
-    private ResponseHeaders getPushResponse(int streamid) {
-        HttpHeadersImpl h = new HttpHeadersImpl();
-        h.addHeader(":status", "200");
-        ResponseHeaders oh = new ResponseHeaders(h);
-        oh.streamid(streamid);
-        return oh;
-    }
-
-    private ByteBuffer getBuffer() {
-        return ByteBuffer.allocate(8 * 1024);
-    }
-
-    private Http2Frame readFrame() throws IOException {
-        byte[] buf = new byte[9];
-        if (is.readNBytes(buf, 0, 9) != 9)
-            throw new IOException("readFrame: connection closed");
-        int len = 0;
-        for (int i = 0; i < 3; i++) {
-            int n = buf[i] & 0xff;
-            //System.err.println("n = " + n);
-            len = (len << 8) + n;
-        }
-        byte[] rest = new byte[len];
-        int n = is.readNBytes(rest, 0, len);
-        if (n != len)
-            throw new IOException("Error reading frame");
-        ByteBufferConsumer bc = new ByteBufferConsumer(
-                new LinkedList<ByteBuffer>(List.of(ByteBuffer.wrap(buf), ByteBuffer.wrap(rest))),
-                this::getBuffer);
-        return Http2Frame.readIncoming(bc);
-    }
-
-    void sendSettingsFrame() throws IOException {
-        sendSettingsFrame(false);
-    }
-
-    void sendSettingsFrame(boolean now) throws IOException {
-        if (serverSettings == null) {
-            serverSettings = SettingsFrame.getDefaultSettings();
-        }
-        if (now) {
-            writeFrame(serverSettings);
-        } else {
-            outputQ.put(serverSettings);
-        }
-    }
-
-    String readUntil(String end) throws IOException {
-        int number = end.length();
-        int found = 0;
-        StringBuilder sb = new StringBuilder();
-        while (found < number) {
-            char expected = end.charAt(found);
-            int c = is.read();
-            if (c == -1) {
-                throw new IOException("Connection closed");
-            }
-            char c0 = (char) c;
-            sb.append(c0);
-            if (c0 != expected) {
-                found = 0;
-                continue;
-            }
-            found++;
-        }
-        return sb.toString();
-    }
-
-    private int getContentLength(String headers) {
-        return getIntHeader(headers, "Content-length");
-    }
-
-    private int getIntHeader(String headers, String name) {
-        String val = getHeader(headers, name);
-        if (val == null) {
-            return -1;
-        }
-        return Integer.parseInt(val);
-    }
-
-    private String getHeader(String headers, String name) {
-        String headers1 = headers.toLowerCase(); // not efficient
-        name = CRLF + name.toLowerCase();
-        int start = headers1.indexOf(name);
-        if (start == -1) {
-            return null;
-        }
-        start += 2;
-        int end = headers1.indexOf(CRLF, start);
-        String line = headers.substring(start, end);
-        start = line.indexOf(':');
-        if (start == -1) {
-            return null;
-        }
-        return line.substring(start + 1).trim();
-    }
-
-    final static String CRLF = "\r\n";
-
-    String readHttp1Request() throws IOException {
-        String headers = readUntil(CRLF + CRLF);
-        int clen = getContentLength(headers);
-        // read the content. There shouldn't be content but ..
-        byte[] buf = new byte[clen];
-        is.readNBytes(buf, 0, clen);
-        String body = new String(buf, "US-ASCII");
-        return headers + body;
-    }
-
-    void sendHttp1Response(int code, String msg, String... headers) throws IOException {
-        StringBuilder sb = new StringBuilder();
-        sb.append("HTTP/1.1 ")
-                .append(code)
-                .append(' ')
-                .append(msg)
-                .append(CRLF);
-        int numheaders = headers.length;
-        for (int i = 0; i < numheaders; i += 2) {
-            sb.append(headers[i])
-                    .append(": ")
-                    .append(headers[i + 1])
-                    .append(CRLF);
-        }
-        sb.append(CRLF);
-        String s = sb.toString();
-        os.write(s.getBytes("US-ASCII"));
-        os.flush();
-    }
-
-    private void unexpectedFrame(Http2Frame frame) {
-        System.err.println("OOPS. Unexpected");
-        assert false;
-    }
-
-    final static ByteBuffer[] bbarray = new ByteBuffer[0];
-
-    // wrapper around a BlockingQueue that throws an exception when it's closed
-    // Each stream has one of these
-
-    String getRequestBody(String request) {
-        int bodystart = request.indexOf(CRLF+CRLF);
-        String body;
-        if (bodystart == -1)
-            body = "";
-        else
-            body = request.substring(bodystart+4);
-        return body;
-    }
-
-    @SuppressWarnings({"rawtypes","unchecked"})
-    void addRequestBodyToQueue(String body, Queue q) throws IOException {
-        ByteBuffer buf = ByteBuffer.wrap(body.getBytes(StandardCharsets.US_ASCII));
-        DataFrame df = new DataFrame();
-        df.streamid(1); // only used for primordial stream
-        df.setData(buf);
-        df.computeLength();
-        df.setFlag(DataFrame.END_STREAM);
-        q.put(df);
-    }
-
-    // window updates done in main reader thread because they may
-    // be used to unblock BodyOutputStreams waiting for WUPs
-
-    HashMap<Integer,Consumer<Integer>> updaters = new HashMap<>();
-
-    void registerStreamWindowUpdater(int streamid, Consumer<Integer> r) {
-        synchronized(updaters) {
-            updaters.put(streamid, r);
-        }
-    }
-
-    int sendWindow = 64 * 1024 - 1; // connection level send window
-
-    /**
-     * BodyOutputStreams call this to get the connection window first.
-     *
-     * @param amount
-     */
-    synchronized void obtainConnectionWindow(int amount) throws InterruptedException {
-       while (amount > 0) {
-           int n = Math.min(amount, sendWindow);
-           amount -= n;
-           sendWindow -= n;
-           if (amount > 0)
-               wait();
-       }
-    }
-
-    synchronized void updateConnectionWindow(int amount) {
-        sendWindow += amount;
-        notifyAll();
-    }
-
-    // simplified output headers class. really just a type safe container
-    // for the hashmap.
-
-    static class ResponseHeaders extends Http2Frame {
-        HttpHeadersImpl headers;
-
-        ResponseHeaders(HttpHeadersImpl headers) {
-            this.headers = headers;
-        }
-
-        @Override
-        void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-            throw new UnsupportedOperationException("Not supported ever!");
-        }
-
-        @Override
-        void computeLength() {
-            throw new UnsupportedOperationException("Not supported ever!");
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/OutgoingPushPromise.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-package java.net.http;
-
-import java.io.*;
-import java.net.*;
-
-// will be converted to a PushPromiseFrame in the writeLoop
-// a thread is then created to produce the DataFrames from the InputStream
-class OutgoingPushPromise extends Http2Frame {
-    final HttpHeadersImpl headers;
-    final URI uri;
-    final InputStream is;
-    final int parentStream; // not the pushed streamid
-
-    OutgoingPushPromise(int parentStream, URI uri, HttpHeadersImpl headers, InputStream is) {
-        this.uri = uri;
-        this.headers = headers;
-        this.is = is;
-        this.parentStream = parentStream;
-    }
-
-    @Override
-    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    @Override
-    void computeLength() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/PushHandler.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net.http;
-
-import java.io.*;
-import java.net.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.net.http.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-public class PushHandler implements Http2Handler {
-
-    final Path tempFile;
-    final int loops;
-
-    public PushHandler(int file_size, int loops) throws Exception {
-        tempFile = TestUtil.getAFile(file_size);
-        this.loops = loops;
-    }
-
-    int invocation = 0;
-
-    public void handle(Http2TestExchange ee) {
-        try {
-            System.err.println ("Server: handle " + ee);
-            invocation++;
-
-            if (ee.serverPushAllowed()) {
-                for (int i=0; i<loops; i++) {
-                    InputStream is = new FileInputStream(tempFile.toFile());
-                    URI u = new URI ("http://www.foo.com/" + Integer.toString(i));
-                    HttpHeadersImpl h = new HttpHeadersImpl();
-                    h.addHeader("X-foo", "bar");
-                    ee.serverPush(u, h, is);
-                }
-                System.err.println ("Server: sent all pushes");
-            }
-            ee.sendResponseHeaders(200, 0);
-            OutputStream os = ee.getResponseBody();
-            InputStream iis = new FileInputStream(tempFile.toFile());
-            iis.transferTo(os);
-            os.close();
-            iis.close();
-        } catch (Exception ex) {
-            System.err.println ("Server: exception " + ex);
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/TestUtil.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net.http;
-
-import java.io.*;
-import java.net.*;
-import java.nio.file.*;
-import java.util.concurrent.*;
-import java.util.Arrays;
-
-public class TestUtil {
-
-    final static String fileContent = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // repeated
-
-    public static Path getAFile(int size) throws IOException {
-        Path p = tempFile();
-        BufferedWriter writer = Files.newBufferedWriter(p);
-        int len = fileContent.length();
-        int iterations = size / len;
-        int remainder = size - (iterations * len);
-        for (int i=0; i<iterations; i++)
-            writer.write(fileContent, 0, len);
-        writer.write(fileContent, 0, remainder);
-        writer.close();
-        return p;
-    }
-
-    public static Path tempFile() {
-        try {
-            Path p = Files.createTempFile("foo", "test");
-            p.toFile().deleteOnExit();
-            return p;
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-    public static Void compareFiles(Path path1, Path path2) {
-        try {
-            if (Files.size(path1) != Files.size(path2))
-                throw new RuntimeException("File sizes do not match");
-            compareContents(path1, path2);
-            return null;
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-    static void compareContents(Path path1, Path path2) {
-        try {
-            byte[] b1 = Files.readAllBytes(path1);
-            byte[] b2 = Files.readAllBytes(path2);
-            if (!Arrays.equals(b1, b2))
-                throw new RuntimeException ("Files do not match");
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BinaryPrimitivesTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.Test;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-import static sun.net.httpclient.hpack.BuffersTestingKit.*;
-import static sun.net.httpclient.hpack.TestHelper.newRandom;
-
-//
-// Some of the tests below overlap in what they test. This allows to diagnose
-// bugs quicker and with less pain by simply ruling out common working bits.
-//
-public final class BinaryPrimitivesTest {
-
-    private final Random rnd = newRandom();
-
-    @Test
-    public void integerRead1() {
-        verifyRead(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
-    }
-
-    @Test
-    public void integerRead2() {
-        verifyRead(bytes(0b00001010), 10, 5);
-    }
-
-    @Test
-    public void integerRead3() {
-        verifyRead(bytes(0b00101010), 42, 8);
-    }
-
-    @Test
-    public void integerWrite1() {
-        verifyWrite(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
-    }
-
-    @Test
-    public void integerWrite2() {
-        verifyWrite(bytes(0b00001010), 10, 5);
-    }
-
-    @Test
-    public void integerWrite3() {
-        verifyWrite(bytes(0b00101010), 42, 8);
-    }
-
-    //
-    // Since readInteger(x) is the inverse of writeInteger(x), thus:
-    //
-    // for all x: readInteger(writeInteger(x)) == x
-    //
-    @Test
-    public void integerIdentity() {
-        final int MAX_VALUE = 1 << 22;
-        int totalCases = 0;
-        int maxFilling = 0;
-        IntegerReader r = new IntegerReader();
-        IntegerWriter w = new IntegerWriter();
-        ByteBuffer buf = ByteBuffer.allocate(8);
-        for (int N = 1; N < 9; N++) {
-            for (int expected = 0; expected <= MAX_VALUE; expected++) {
-                w.reset().configure(expected, N, 1).write(buf);
-                buf.flip();
-                totalCases++;
-                maxFilling = Math.max(maxFilling, buf.remaining());
-                r.reset().configure(N).read(buf);
-                assertEquals(r.get(), expected);
-                buf.clear();
-            }
-        }
-        System.out.printf("totalCases: %,d, maxFilling: %,d, maxValue: %,d%n",
-                totalCases, maxFilling, MAX_VALUE);
-    }
-
-    @Test
-    public void integerReadChunked() {
-        final int NUM_TESTS = 1024;
-        IntegerReader r = new IntegerReader();
-        ByteBuffer bb = ByteBuffer.allocate(8);
-        IntegerWriter w = new IntegerWriter();
-        for (int i = 0; i < NUM_TESTS; i++) {
-            final int N = 1 + rnd.nextInt(8);
-            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
-            w.reset().configure(expected, N, rnd.nextInt()).write(bb);
-            bb.flip();
-
-            forEachSplit(bb,
-                    (buffers) -> {
-                        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
-                        r.configure(N);
-                        for (ByteBuffer b : buf) {
-                            r.read(b);
-                        }
-                        assertEquals(r.get(), expected);
-                        r.reset();
-                    });
-            bb.clear();
-        }
-    }
-
-    // FIXME: use maxValue in the test
-
-    @Test
-    // FIXME: tune values for better coverage
-    public void integerWriteChunked() {
-        ByteBuffer bb = ByteBuffer.allocate(6);
-        IntegerWriter w = new IntegerWriter();
-        IntegerReader r = new IntegerReader();
-        for (int i = 0; i < 1024; i++) { // number of tests
-            final int N = 1 + rnd.nextInt(8);
-            final int payload = rnd.nextInt(255);
-            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
-
-            forEachSplit(bb,
-                    (buffers) -> {
-                        List<ByteBuffer> buf = new ArrayList<>();
-                        relocateBuffers(injectEmptyBuffers(buffers)).forEach(buf::add);
-                        boolean written = false;
-                        w.configure(expected, N, payload); // TODO: test for payload it can be read after written
-                        for (ByteBuffer b : buf) {
-                            int pos = b.position();
-                            written = w.write(b);
-                            b.position(pos);
-                        }
-                        if (!written) {
-                            fail("please increase bb size");
-                        }
-                        r.configure(N).read(concat(buf));
-                        // TODO: check payload here
-                        assertEquals(r.get(), expected);
-                        w.reset();
-                        r.reset();
-                        bb.clear();
-                    });
-        }
-    }
-
-
-    //
-    // Since readString(x) is the inverse of writeString(x), thus:
-    //
-    // for all x: readString(writeString(x)) == x
-    //
-    @Test
-    public void stringIdentity() {
-        final int MAX_STRING_LENGTH = 4096;
-        ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6); // it takes 6 bytes to encode string length of Integer.MAX_VALUE
-        CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
-        StringReader reader = new StringReader();
-        StringWriter writer = new StringWriter();
-        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
-            for (int i = 0; i < 64; i++) {
-                // not so much "test in isolation", I know... we're testing .reset() as well
-                bytes.clear();
-                chars.clear();
-
-                byte[] b = new byte[len];
-                rnd.nextBytes(b);
-
-                String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
-
-                boolean written = writer
-                        .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
-                        .write(bytes);
-
-                if (!written) {
-                    fail("please increase 'bytes' size");
-                }
-                bytes.flip();
-                reader.read(bytes, chars);
-                chars.flip();
-                assertEquals(chars.toString(), expected);
-                reader.reset();
-                writer.reset();
-            }
-        }
-    }
-
-//    @Test
-//    public void huffmanStringWriteChunked() {
-//        fail();
-//    }
-//
-//    @Test
-//    public void huffmanStringReadChunked() {
-//        fail();
-//    }
-
-    @Test
-    public void stringWriteChunked() {
-        final int MAX_STRING_LENGTH = 8;
-        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
-        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
-        final StringReader reader = new StringReader();
-        final StringWriter writer = new StringWriter();
-        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
-
-            byte[] b = new byte[len];
-            rnd.nextBytes(b);
-
-            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
-
-            forEachSplit(bytes, (buffers) -> {
-                writer.configure(expected, 0, expected.length(), false);
-                boolean written = false;
-                for (ByteBuffer buf : buffers) {
-                    int p0 = buf.position();
-                    written = writer.write(buf);
-                    buf.position(p0);
-                }
-                if (!written) {
-                    fail("please increase 'bytes' size");
-                }
-                reader.read(concat(buffers), chars);
-                chars.flip();
-                assertEquals(chars.toString(), expected);
-                reader.reset();
-                writer.reset();
-                chars.clear();
-                bytes.clear();
-            });
-        }
-    }
-
-    @Test
-    public void stringReadChunked() {
-        final int MAX_STRING_LENGTH = 16;
-        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
-        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
-        final StringReader reader = new StringReader();
-        final StringWriter writer = new StringWriter();
-        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
-
-            byte[] b = new byte[len];
-            rnd.nextBytes(b);
-
-            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
-
-            boolean written = writer
-                    .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
-                    .write(bytes);
-            writer.reset();
-
-            if (!written) {
-                fail("please increase 'bytes' size");
-            }
-            bytes.flip();
-
-            forEachSplit(bytes, (buffers) -> {
-                for (ByteBuffer buf : buffers) {
-                    int p0 = buf.position();
-                    reader.read(buf, chars);
-                    buf.position(p0);
-                }
-                chars.flip();
-                assertEquals(chars.toString(), expected);
-                reader.reset();
-                chars.clear();
-            });
-
-            bytes.clear();
-        }
-    }
-
-//    @Test
-//    public void test_Huffman_String_Identity() {
-//        StringWriter writer = new StringWriter();
-//        StringReader reader = new StringReader();
-//        // 256 * 8 gives 2048 bits in case of plain 8 bit coding
-//        // 256 * 30 gives you 7680 bits or 960 bytes in case of almost
-//        //          improbable event of 256 30 bits symbols in a row
-//        ByteBuffer binary = ByteBuffer.allocate(960);
-//        CharBuffer text = CharBuffer.allocate(960 / 5); // 5 = minimum code length
-//        for (int len = 0; len < 128; len++) {
-//            for (int i = 0; i < 256; i++) {
-//                // not so much "test in isolation", I know...
-//                binary.clear();
-//
-//                byte[] bytes = new byte[len];
-//                rnd.nextBytes(bytes);
-//
-//                String s = new String(bytes, StandardCharsets.ISO_8859_1);
-//
-//                writer.write(CharBuffer.wrap(s), binary, true);
-//                binary.flip();
-//                reader.read(binary, text);
-//                text.flip();
-//                assertEquals(text.toString(), s);
-//            }
-//        }
-//    }
-
-    // TODO: atomic failures: e.g. readonly/overflow
-
-    private static byte[] bytes(int... data) {
-        byte[] bytes = new byte[data.length];
-        for (int i = 0; i < data.length; i++) {
-            bytes[i] = (byte) data[i];
-        }
-        return bytes;
-    }
-
-    private static void verifyRead(byte[] data, int expected, int N) {
-        ByteBuffer buf = ByteBuffer.wrap(data, 0, data.length);
-        IntegerReader reader = new IntegerReader();
-        reader.configure(N).read(buf);
-        assertEquals(expected, reader.get());
-    }
-
-    private void verifyWrite(byte[] expected, int data, int N) {
-        IntegerWriter w = new IntegerWriter();
-        ByteBuffer buf = ByteBuffer.allocate(2 * expected.length);
-        w.configure(data, N, 1).write(buf);
-        buf.flip();
-        assertEquals(ByteBuffer.wrap(expected), buf);
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BuffersTestingKit.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.*;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-import static java.nio.ByteBuffer.allocate;
-
-public final class BuffersTestingKit {
-
-    /**
-     * Relocates a {@code [position, limit)} region of the given buffer to
-     * corresponding region in a new buffer starting with provided {@code
-     * newPosition}.
-     *
-     * <p> Might be useful to make sure ByteBuffer's users do not rely on any
-     * absolute positions, but solely on what's reported by position(), limit().
-     *
-     * <p> The contents between the given buffer and the returned one are not
-     * shared.
-     */
-    public static ByteBuffer relocate(ByteBuffer buffer, int newPosition,
-                                      int newCapacity) {
-        int oldPosition = buffer.position();
-        int oldLimit = buffer.limit();
-
-        if (newPosition + oldLimit - oldPosition > newCapacity) {
-            throw new IllegalArgumentException();
-        }
-
-        ByteBuffer result;
-        if (buffer.isDirect()) {
-            result = ByteBuffer.allocateDirect(newCapacity);
-        } else {
-            result = allocate(newCapacity);
-        }
-
-        result.position(newPosition);
-        result.put(buffer).limit(result.position()).position(newPosition);
-        buffer.position(oldPosition);
-
-        if (buffer.isReadOnly()) {
-            return result.asReadOnlyBuffer();
-        }
-        return result;
-    }
-
-    public static Iterable<? extends ByteBuffer> relocateBuffers(
-            Iterable<? extends ByteBuffer> source) {
-        return () ->
-                new Iterator<ByteBuffer>() {
-
-                    private final Iterator<? extends ByteBuffer> it = source.iterator();
-
-                    @Override
-                    public boolean hasNext() {
-                        return it.hasNext();
-                    }
-
-                    @Override
-                    public ByteBuffer next() {
-                        ByteBuffer buf = it.next();
-                        int remaining = buf.remaining();
-                        int newCapacity = remaining + random.nextInt(17);
-                        int newPosition = random.nextInt(newCapacity - remaining + 1);
-                        return relocate(buf, newPosition, newCapacity);
-                    }
-                };
-    }
-
-    // TODO: not always of size 0 (it's fine for buffer to report !b.hasRemaining())
-    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
-            Iterable<? extends ByteBuffer> source) {
-        return injectEmptyBuffers(source, () -> allocate(0));
-    }
-
-    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
-            Iterable<? extends ByteBuffer> source,
-            Supplier<? extends ByteBuffer> emptyBufferFactory) {
-
-        return () ->
-                new Iterator<ByteBuffer>() {
-
-                    private final Iterator<? extends ByteBuffer> it = source.iterator();
-                    private ByteBuffer next = calculateNext();
-
-                    private ByteBuffer calculateNext() {
-                        if (random.nextBoolean()) {
-                            return emptyBufferFactory.get();
-                        } else if (it.hasNext()) {
-                            return it.next();
-                        } else {
-                            return null;
-                        }
-                    }
-
-                    @Override
-                    public boolean hasNext() {
-                        return next != null;
-                    }
-
-                    @Override
-                    public ByteBuffer next() {
-                        if (!hasNext()) {
-                            throw new NoSuchElementException();
-                        }
-                        ByteBuffer next = this.next;
-                        this.next = calculateNext();
-                        return next;
-                    }
-                };
-    }
-
-    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split) {
-        return concat(split, ByteBuffer::allocate);
-    }
-
-    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split,
-                                    Function<? super Integer, ? extends ByteBuffer> concatBufferFactory) {
-        int size = 0;
-        for (ByteBuffer bb : split) {
-            size += bb.remaining();
-        }
-
-        ByteBuffer result = concatBufferFactory.apply(size);
-        for (ByteBuffer bb : split) {
-            result.put(bb);
-        }
-
-        result.flip();
-        return result;
-    }
-
-    public static void forEachSplit(ByteBuffer bb,
-                                    Consumer<? super Iterable<? extends ByteBuffer>> action) {
-        forEachSplit(bb.remaining(),
-                (lengths) -> {
-                    int end = bb.position();
-                    List<ByteBuffer> buffers = new LinkedList<>();
-                    for (int len : lengths) {
-                        ByteBuffer d = bb.duplicate();
-                        d.position(end);
-                        d.limit(end + len);
-                        end += len;
-                        buffers.add(d);
-                    }
-                    action.accept(buffers);
-                });
-    }
-
-    private static void forEachSplit(int n, Consumer<? super Iterable<? extends Integer>> action) {
-        forEachSplit(n, new Stack<>(), action);
-    }
-
-    private static void forEachSplit(int n, Stack<Integer> path,
-                                     Consumer<? super Iterable<? extends Integer>> action) {
-        if (n == 0) {
-            action.accept(path);
-        } else {
-            for (int i = 1; i <= n; i++) {
-                path.push(i);
-                forEachSplit(n - i, path, action);
-                path.pop();
-            }
-        }
-    }
-
-    private static final Random random = new Random();
-
-    private BuffersTestingKit() {
-        throw new InternalError();
-    }
-
-//    public static void main(String[] args) {
-//
-//        List<ByteBuffer> buffers = Arrays.asList(
-//                (ByteBuffer) allocate(3).position(1).limit(2),
-//                allocate(0),
-//                allocate(7));
-//
-//        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
-//        List<ByteBuffer> result = new ArrayList<>();
-//        buf.forEach(result::add);
-//        System.out.println(result);
-//    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/CircularBufferTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-import sun.net.httpclient.hpack.HeaderTable.CircularBuffer;
-
-import java.util.Queue;
-import java.util.Random;
-import java.util.concurrent.ArrayBlockingQueue;
-
-import static org.testng.Assert.assertEquals;
-import static sun.net.httpclient.hpack.TestHelper.newRandom;
-
-public final class CircularBufferTest {
-
-    private final Random r = newRandom();
-
-    @BeforeClass
-    public void setUp() {
-        r.setSeed(System.currentTimeMillis());
-    }
-
-    @Test
-    public void queue() {
-        for (int capacity = 1; capacity <= 2048; capacity++) {
-            queueOnce(capacity, 32);
-        }
-    }
-
-    @Test
-    public void resize() {
-        for (int capacity = 1; capacity <= 4096; capacity++) {
-            resizeOnce(capacity);
-        }
-    }
-
-    @Test
-    public void downSizeEmptyBuffer() {
-        CircularBuffer<Integer> buffer = new CircularBuffer<>(16);
-        buffer.resize(15);
-    }
-
-    private void resizeOnce(int capacity) {
-
-        int nextNumberToPut = 0;
-
-        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
-        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
-
-        // Fill full, so the next add will wrap
-        for (int i = 0; i < capacity; i++, nextNumberToPut++) {
-            buffer.add(nextNumberToPut);
-            referenceQueue.add(nextNumberToPut);
-        }
-        int gets = r.nextInt(capacity); // [0, capacity)
-        for (int i = 0; i < gets; i++) {
-            referenceQueue.poll();
-            buffer.remove();
-        }
-        int puts = r.nextInt(gets + 1); // [0, gets]
-        for (int i = 0; i < puts; i++, nextNumberToPut++) {
-            buffer.add(nextNumberToPut);
-            referenceQueue.add(nextNumberToPut);
-        }
-
-        Integer[] expected = referenceQueue.toArray(new Integer[0]);
-        buffer.resize(expected.length);
-
-        assertEquals(buffer.elements, expected);
-    }
-
-    private void queueOnce(int capacity, int numWraps) {
-
-        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
-        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
-
-        int nextNumberToPut = 0;
-        int totalPuts = 0;
-        int putsLimit = capacity * numWraps;
-        int remainingCapacity = capacity;
-        int size = 0;
-
-        while (totalPuts < putsLimit) {
-            assert remainingCapacity + size == capacity;
-            int puts = r.nextInt(remainingCapacity + 1); // [0, remainingCapacity]
-            remainingCapacity -= puts;
-            size += puts;
-            for (int i = 0; i < puts; i++, nextNumberToPut++) {
-                referenceQueue.add(nextNumberToPut);
-                buffer.add(nextNumberToPut);
-            }
-            totalPuts += puts;
-            int gets = r.nextInt(size + 1); // [0, size]
-            size -= gets;
-            remainingCapacity += gets;
-            for (int i = 0; i < gets; i++) {
-                Integer expected = referenceQueue.poll();
-                Integer actual = buffer.remove();
-                assertEquals(actual, expected);
-            }
-        }
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/DecoderTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,689 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.Test;
-
-import java.io.UncheckedIOException;
-import java.net.ProtocolException;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static sun.net.httpclient.hpack.TestHelper.*;
-
-//
-// Tests whose names start with "testX" are the ones captured from real HPACK
-// use cases
-//
-public final class DecoderTest {
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
-    //
-    @Test
-    public void example1() {
-        // @formatter:off
-        test("400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
-             "746f 6d2d 6865 6164 6572",
-
-             "[  1] (s =  55) custom-key: custom-header\n" +
-             "      Table size:  55",
-
-             "custom-key: custom-header");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
-    //
-    @Test
-    public void example2() {
-        // @formatter:off
-        test("040c 2f73 616d 706c 652f 7061 7468",
-             "empty.",
-             ":path: /sample/path");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
-    //
-    @Test
-    public void example3() {
-        // @formatter:off
-        test("1008 7061 7373 776f 7264 0673 6563 7265\n" +
-             "74",
-             "empty.",
-             "password: secret");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
-    //
-    @Test
-    public void example4() {
-        // @formatter:off
-        test("82",
-             "empty.",
-             ":method: GET");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.3
-    //
-    @Test
-    public void example5() {
-        // @formatter:off
-        Decoder d = new Decoder(256);
-
-        test(d, "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
-                "2e63 6f6d",
-
-                "[  1] (s =  57) :authority: www.example.com\n" +
-                "      Table size:  57",
-
-                ":method: GET\n" +
-                ":scheme: http\n" +
-                ":path: /\n" +
-                ":authority: www.example.com");
-
-        test(d, "8286 84be 5808 6e6f 2d63 6163 6865",
-
-                "[  1] (s =  53) cache-control: no-cache\n" +
-                "[  2] (s =  57) :authority: www.example.com\n" +
-                "      Table size: 110",
-
-                ":method: GET\n" +
-                ":scheme: http\n" +
-                ":path: /\n" +
-                ":authority: www.example.com\n" +
-                "cache-control: no-cache");
-
-        test(d, "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
-                "0c63 7573 746f 6d2d 7661 6c75 65",
-
-                "[  1] (s =  54) custom-key: custom-value\n" +
-                "[  2] (s =  53) cache-control: no-cache\n" +
-                "[  3] (s =  57) :authority: www.example.com\n" +
-                "      Table size: 164",
-
-                ":method: GET\n" +
-                ":scheme: https\n" +
-                ":path: /index.html\n" +
-                ":authority: www.example.com\n" +
-                "custom-key: custom-value");
-
-        // @formatter:on
-    }
-
-    @Test
-    public void example5AllSplits() {
-        // @formatter:off
-        testAllSplits(
-                "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
-                "2e63 6f6d",
-
-                "[  1] (s =  57) :authority: www.example.com\n" +
-                "      Table size:  57",
-
-                ":method: GET\n" +
-                ":scheme: http\n" +
-                ":path: /\n" +
-                ":authority: www.example.com");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.4
-    //
-    @Test
-    public void example6() {
-        // @formatter:off
-        Decoder d = new Decoder(256);
-
-        test(d, "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
-                "ff",
-
-                "[  1] (s =  57) :authority: www.example.com\n" +
-                "      Table size:  57",
-
-                ":method: GET\n" +
-                ":scheme: http\n" +
-                ":path: /\n" +
-                ":authority: www.example.com");
-
-        test(d, "8286 84be 5886 a8eb 1064 9cbf",
-
-                "[  1] (s =  53) cache-control: no-cache\n" +
-                "[  2] (s =  57) :authority: www.example.com\n" +
-                "      Table size: 110",
-
-                ":method: GET\n" +
-                ":scheme: http\n" +
-                ":path: /\n" +
-                ":authority: www.example.com\n" +
-                "cache-control: no-cache");
-
-        test(d, "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
-                "a849 e95b b8e8 b4bf",
-
-                "[  1] (s =  54) custom-key: custom-value\n" +
-                "[  2] (s =  53) cache-control: no-cache\n" +
-                "[  3] (s =  57) :authority: www.example.com\n" +
-                "      Table size: 164",
-
-                ":method: GET\n" +
-                ":scheme: https\n" +
-                ":path: /index.html\n" +
-                ":authority: www.example.com\n" +
-                "custom-key: custom-value");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.5
-    //
-    @Test
-    public void example7() {
-        // @formatter:off
-        Decoder d = new Decoder(256);
-
-        test(d, "4803 3330 3258 0770 7269 7661 7465 611d\n" +
-                "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
-                "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
-                "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
-                "6c65 2e63 6f6d",
-
-                "[  1] (s =  63) location: https://www.example.com\n" +
-                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "[  3] (s =  52) cache-control: private\n" +
-                "[  4] (s =  42) :status: 302\n" +
-                "      Table size: 222",
-
-                ":status: 302\n" +
-                "cache-control: private\n" +
-                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "location: https://www.example.com");
-
-        test(d, "4803 3330 37c1 c0bf",
-
-                "[  1] (s =  42) :status: 307\n" +
-                "[  2] (s =  63) location: https://www.example.com\n" +
-                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "[  4] (s =  52) cache-control: private\n" +
-                "      Table size: 222",
-
-                ":status: 307\n" +
-                "cache-control: private\n" +
-                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "location: https://www.example.com");
-
-        test(d, "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
-                "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
-                "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
-                "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
-                "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
-                "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
-                "3d31",
-
-                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
-                "[  2] (s =  52) content-encoding: gzip\n" +
-                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
-                "      Table size: 215",
-
-                ":status: 200\n" +
-                "cache-control: private\n" +
-                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
-                "location: https://www.example.com\n" +
-                "content-encoding: gzip\n" +
-                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.6
-    //
-    @Test
-    public void example8() {
-        // @formatter:off
-        Decoder d = new Decoder(256);
-
-        test(d, "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
-                "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
-                "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
-                "e9ae 82ae 43d3",
-
-                "[  1] (s =  63) location: https://www.example.com\n" +
-                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "[  3] (s =  52) cache-control: private\n" +
-                "[  4] (s =  42) :status: 302\n" +
-                "      Table size: 222",
-
-                ":status: 302\n" +
-                "cache-control: private\n" +
-                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "location: https://www.example.com");
-
-        test(d, "4883 640e ffc1 c0bf",
-
-                "[  1] (s =  42) :status: 307\n" +
-                "[  2] (s =  63) location: https://www.example.com\n" +
-                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "[  4] (s =  52) cache-control: private\n" +
-                "      Table size: 222",
-
-                ":status: 307\n" +
-                "cache-control: private\n" +
-                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-                "location: https://www.example.com");
-
-        test(d, "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
-                "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
-                "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
-                "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
-                "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
-
-                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
-                "[  2] (s =  52) content-encoding: gzip\n" +
-                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
-                "      Table size: 215",
-
-                ":status: 200\n" +
-                "cache-control: private\n" +
-                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
-                "location: https://www.example.com\n" +
-                "content-encoding: gzip\n" +
-                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
-        // @formatter:on
-    }
-
-    @Test
-    // One of responses from Apache Server that helped to catch a bug
-    public void testX() {
-        Decoder d = new Decoder(4096);
-        // @formatter:off
-        test(d, "3fe1 1f88 6196 d07a be94 03ea 693f 7504\n" +
-                "00b6 a05c b827 2e32 fa98 b46f 769e 86b1\n" +
-                "9272 b025 da5c 2ea9 fd70 a8de 7fb5 3556\n" +
-                "5ab7 6ece c057 02e2 2ad2 17bf 6c96 d07a\n" +
-                "be94 0854 cb6d 4a08 0075 40bd 71b6 6e05\n" +
-                "a531 68df 0f13 8efe 4522 cd32 21b6 5686\n" +
-                "eb23 781f cf52 848f d24a 8f0f 0d02 3435\n" +
-                "5f87 497c a589 d34d 1f",
-
-                "[  1] (s =  53) content-type: text/html\n" +
-                "[  2] (s =  50) accept-ranges: bytes\n" +
-                "[  3] (s =  74) last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
-                "[  4] (s =  77) server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
-                "[  5] (s =  65) date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
-                "      Table size: 319",
-
-                ":status: 200\n" +
-                "date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
-                "server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
-                "last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
-                "etag: \"2d-432a5e4a73a80\"\n" +
-                "accept-ranges: bytes\n" +
-                "content-length: 45\n" +
-                "content-type: text/html");
-        // @formatter:on
-    }
-
-    @Test
-    public void testX1() {
-        // Supplier of a decoder with a particular state
-        Supplier<Decoder> s = () -> {
-            Decoder d = new Decoder(4096);
-            // @formatter:off
-            test(d, "88 76 92 ca 54 a7 d7 f4 fa ec af ed 6d da 61 d7 bb 1e ad ff" +
-                    "df 61 97 c3 61 be 94 13 4a 65 b6 a5 04 00 b8 a0 5a b8 db 77" +
-                    "1b 71 4c 5a 37 ff 0f 0d 84 08 00 00 03",
-
-                    "[  1] (s =  65) date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
-                    "[  2] (s =  59) server: Jetty(9.3.z-SNAPSHOT)\n" +
-                    "      Table size: 124",
-
-                    ":status: 200\n" +
-                    "server: Jetty(9.3.z-SNAPSHOT)\n" +
-                    "date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
-                    "content-length: 100000"
-            );
-            // @formatter:on
-            return d;
-        };
-        // For all splits of the following data fed to the supplied decoder we
-        // must get what's expected
-        // @formatter:off
-        testAllSplits(s,
-                "88 bf be 0f 0d 84 08 00 00 03",
-
-                "[  1] (s =  65) date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
-                "[  2] (s =  59) server: Jetty(9.3.z-SNAPSHOT)\n" +
-                "      Table size: 124",
-
-                ":status: 200\n" +
-                "server: Jetty(9.3.z-SNAPSHOT)\n" +
-                "date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
-                "content-length: 100000");
-        // @formatter:on
-    }
-
-    //
-    // This test is missing in the spec
-    //
-    @Test
-    public void sizeUpdate() {
-        Decoder d = new Decoder(4096);
-        assertEquals(d.getTable().maxSize(), 4096);
-        d.decode(ByteBuffer.wrap(new byte[]{0b00111110}), true, nopCallback()); // newSize = 30
-        assertEquals(d.getTable().maxSize(), 30);
-    }
-
-    @Test
-    public void incorrectSizeUpdate() {
-        ByteBuffer b = ByteBuffer.allocate(8);
-        Encoder e = new Encoder(8192) {
-            @Override
-            protected int calculateCapacity(int maxCapacity) {
-                return maxCapacity;
-            }
-        };
-        e.header("a", "b");
-        e.encode(b);
-        b.flip();
-        {
-            Decoder d = new Decoder(4096);
-            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
-                    () -> d.decode(b, true, (name, value) -> { }));
-
-            assertNotNull(ex.getCause());
-            assertEquals(ex.getCause().getClass(), ProtocolException.class);
-        }
-        b.flip();
-        {
-            Decoder d = new Decoder(4096);
-            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
-                    () -> d.decode(b, false, (name, value) -> { }));
-
-            assertNotNull(ex.getCause());
-            assertEquals(ex.getCause().getClass(), ProtocolException.class);
-        }
-    }
-
-    @Test
-    public void corruptedHeaderBlockInteger() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                (byte) 0b11111111, // indexed
-                (byte) 0b10011010  // 25 + ...
-        });
-        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
-                () -> d.decode(data, true, nopCallback()));
-        assertNotNull(e.getCause());
-        assertEquals(e.getCause().getClass(), ProtocolException.class);
-        assertExceptionMessageContains(e, "Unexpected end of header block");
-    }
-
-    // 5.1.  Integer Representation
-    // ...
-    // Integer encodings that exceed implementation limits -- in value or octet
-    // length -- MUST be treated as decoding errors. Different limits can
-    // be set for each of the different uses of integers, based on
-    // implementation constraints.
-    @Test
-    public void headerBlockIntegerNoOverflow() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                (byte) 0b11111111, // indexed + 127
-                // Integer.MAX_VALUE - 127 (base 128, little-endian):
-                (byte) 0b10000000,
-                (byte) 0b11111111,
-                (byte) 0b11111111,
-                (byte) 0b11111111,
-                (byte) 0b00000111
-        });
-
-        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
-                () -> d.decode(data, true, nopCallback()));
-
-        assertExceptionMessageContains(e, "index=2147483647");
-    }
-
-    @Test
-    public void headerBlockIntegerOverflow() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                (byte) 0b11111111, // indexed + 127
-                // Integer.MAX_VALUE - 127 + 1 (base 128, little endian):
-                (byte) 0b10000001,
-                (byte) 0b11111111,
-                (byte) 0b11111111,
-                (byte) 0b11111111,
-                (byte) 0b00000111
-        });
-
-        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
-                () -> d.decode(data, true, nopCallback()));
-
-        assertExceptionMessageContains(e, "Integer overflow");
-    }
-
-    @Test
-    public void corruptedHeaderBlockString1() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                0b00001111, // literal, index=15
-                0b00000000,
-                0b00001000, // huffman=false, length=8
-                0b00000000, // \
-                0b00000000, //  but only 3 octets available...
-                0b00000000  // /
-        });
-        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
-                () -> d.decode(data, true, nopCallback()));
-        assertNotNull(e.getCause());
-        assertEquals(e.getCause().getClass(), ProtocolException.class);
-        assertExceptionMessageContains(e, "Unexpected end of header block");
-    }
-
-    @Test
-    public void corruptedHeaderBlockString2() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                0b00001111, // literal, index=15
-                0b00000000,
-                (byte) 0b10001000, // huffman=true, length=8
-                0b00000000, // \
-                0b00000000, //  \
-                0b00000000, //   but only 5 octets available...
-                0b00000000, //  /
-                0b00000000  // /
-        });
-        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
-                () -> d.decode(data, true, nopCallback()));
-        assertNotNull(e.getCause());
-        assertEquals(e.getCause().getClass(), ProtocolException.class);
-        assertExceptionMessageContains(e, "Unexpected end of header block");
-    }
-
-    // 5.2.  String Literal Representation
-    // ...A Huffman-encoded string literal containing the EOS symbol MUST be
-    // treated as a decoding error...
-    @Test
-    public void corruptedHeaderBlockHuffmanStringEOS() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                0b00001111, // literal, index=15
-                0b00000000,
-                (byte) 0b10000110, // huffman=true, length=6
-                0b00011001, 0b01001101, (byte) 0b11111111,
-                (byte) 0b11111111, (byte) 0b11111111, (byte) 0b11111100
-        });
-        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
-                () -> d.decode(data, true, nopCallback()));
-
-        assertExceptionMessageContains(e, "Encountered EOS");
-    }
-
-    // 5.2.  String Literal Representation
-    // ...A padding strictly longer than 7 bits MUST be treated as a decoding
-    // error...
-    @Test
-    public void corruptedHeaderBlockHuffmanStringLongPadding1() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                0b00001111, // literal, index=15
-                0b00000000,
-                (byte) 0b10000011, // huffman=true, length=3
-                0b00011001, 0b01001101, (byte) 0b11111111
-                // len("aei") + len(padding) = (5 + 5 + 5) + (9)
-        });
-        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
-                () -> d.decode(data, true, nopCallback()));
-
-        assertExceptionMessageContains(e, "Padding is too long", "len=9");
-    }
-
-    @Test
-    public void corruptedHeaderBlockHuffmanStringLongPadding2() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                0b00001111, // literal, index=15
-                0b00000000,
-                (byte) 0b10000011, // huffman=true, length=3
-                0b00011001, 0b01111010, (byte) 0b11111111
-                // len("aek") + len(padding) = (5 + 5 + 7) + (7)
-        });
-        assertVoidDoesNotThrow(() -> d.decode(data, true, nopCallback()));
-    }
-
-    // 5.2.  String Literal Representation
-    // ...A padding not corresponding to the most significant bits of the code
-    // for the EOS symbol MUST be treated as a decoding error...
-    @Test
-    public void corruptedHeaderBlockHuffmanStringNotEOSPadding() {
-        Decoder d = new Decoder(4096);
-        ByteBuffer data = ByteBuffer.wrap(new byte[]{
-                0b00001111, // literal, index=15
-                0b00000000,
-                (byte) 0b10000011, // huffman=true, length=3
-                0b00011001, 0b01111010, (byte) 0b11111110
-        });
-        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
-                () -> d.decode(data, true, nopCallback()));
-
-        assertExceptionMessageContains(e, "Not a EOS prefix");
-    }
-
-    @Test
-    public void argsTestBiConsumerIsNull() {
-        Decoder decoder = new Decoder(4096);
-        assertVoidThrows(NullPointerException.class,
-                () -> decoder.decode(ByteBuffer.allocate(16), true, null));
-    }
-
-    @Test
-    public void argsTestByteBufferIsNull() {
-        Decoder decoder = new Decoder(4096);
-        assertVoidThrows(NullPointerException.class,
-                () -> decoder.decode(null, true, nopCallback()));
-    }
-
-    @Test
-    public void argsTestBothAreNull() {
-        Decoder decoder = new Decoder(4096);
-        assertVoidThrows(NullPointerException.class,
-                () -> decoder.decode(null, true, null));
-    }
-
-    private static void test(String hexdump,
-                             String headerTable, String headerList) {
-        test(new Decoder(4096), hexdump, headerTable, headerList);
-    }
-
-    private static void testAllSplits(String hexdump,
-                                      String expectedHeaderTable,
-                                      String expectedHeaderList) {
-        testAllSplits(() -> new Decoder(256), hexdump, expectedHeaderTable, expectedHeaderList);
-    }
-
-    private static void testAllSplits(Supplier<Decoder> supplier, String hexdump,
-                                      String expectedHeaderTable, String expectedHeaderList) {
-        ByteBuffer source = SpecHelper.toBytes(hexdump);
-
-        BuffersTestingKit.forEachSplit(source, iterable -> {
-            List<String> actual = new LinkedList<>();
-            Iterator<? extends ByteBuffer> i = iterable.iterator();
-            if (!i.hasNext()) {
-                return;
-            }
-            Decoder d = supplier.get();
-            do {
-                ByteBuffer n = i.next();
-                d.decode(n, !i.hasNext(), (name, value) -> {
-                    if (value == null) {
-                        actual.add(name.toString());
-                    } else {
-                        actual.add(name + ": " + value);
-                    }
-                });
-            } while (i.hasNext());
-            assertEquals(d.getTable().getStateString(), expectedHeaderTable);
-            assertEquals(actual.stream().collect(Collectors.joining("\n")), expectedHeaderList);
-        });
-    }
-
-    //
-    // Sometimes we need to keep the same decoder along several runs,
-    // as it models the same connection
-    //
-    private static void test(Decoder d, String hexdump,
-                             String expectedHeaderTable, String expectedHeaderList) {
-
-        ByteBuffer source = SpecHelper.toBytes(hexdump);
-
-        List<String> actual = new LinkedList<>();
-        d.decode(source, true, (name, value) -> {
-            if (value == null) {
-                actual.add(name.toString());
-            } else {
-                actual.add(name + ": " + value);
-            }
-        });
-
-        assertEquals(d.getTable().getStateString(), expectedHeaderTable);
-        assertEquals(actual.stream().collect(Collectors.joining("\n")), expectedHeaderList);
-    }
-
-    private static DecodingCallback nopCallback() {
-        return (t, u) -> { };
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/EncoderTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,692 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.Test;
-
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import static sun.net.httpclient.hpack.BuffersTestingKit.concat;
-import static sun.net.httpclient.hpack.BuffersTestingKit.forEachSplit;
-import static sun.net.httpclient.hpack.SpecHelper.toHexdump;
-import static sun.net.httpclient.hpack.TestHelper.assertVoidThrows;
-import static java.util.Arrays.asList;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-// TODO: map textual representation of commands from the spec to actual
-// calls to encoder (actually, this is a good idea for decoder as well)
-public final class EncoderTest {
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
-    //
-    @Test
-    public void example1() {
-
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        e.literalWithIndexing("custom-key", false, "custom-header", false);
-        // @formatter:off
-        test(e,
-
-             "400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
-             "746f 6d2d 6865 6164 6572",
-
-             "[  1] (s =  55) custom-key: custom-header\n" +
-             "      Table size:  55");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
-    //
-    @Test
-    public void example2() {
-
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        e.literal(4, "/sample/path", false);
-        // @formatter:off
-        test(e,
-
-             "040c 2f73 616d 706c 652f 7061 7468",
-
-             "empty.");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
-    //
-    @Test
-    public void example3() {
-
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        e.literalNeverIndexed("password", false, "secret", false);
-        // @formatter:off
-        test(e,
-
-             "1008 7061 7373 776f 7264 0673 6563 7265\n" +
-             "74",
-
-             "empty.");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
-    //
-    @Test
-    public void example4() {
-
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        e.indexed(2);
-        // @formatter:off
-        test(e,
-
-             "82",
-
-             "empty.");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.3
-    //
-    @Test
-    public void example5() {
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        ByteBuffer output = ByteBuffer.allocate(64);
-        e.indexed(2);
-        e.encode(output);
-        e.indexed(6);
-        e.encode(output);
-        e.indexed(4);
-        e.encode(output);
-        e.literalWithIndexing(1, "www.example.com", false);
-        e.encode(output);
-
-        output.flip();
-
-        // @formatter:off
-        test(e, output,
-
-             "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
-             "2e63 6f6d",
-
-             "[  1] (s =  57) :authority: www.example.com\n" +
-             "      Table size:  57");
-
-        output.clear();
-
-        e.indexed( 2);
-        e.encode(output);
-        e.indexed( 6);
-        e.encode(output);
-        e.indexed( 4);
-        e.encode(output);
-        e.indexed(62);
-        e.encode(output);
-        e.literalWithIndexing(24, "no-cache", false);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "8286 84be 5808 6e6f 2d63 6163 6865",
-
-             "[  1] (s =  53) cache-control: no-cache\n" +
-             "[  2] (s =  57) :authority: www.example.com\n" +
-             "      Table size: 110");
-
-        output.clear();
-
-        e.indexed( 2);
-        e.encode(output);
-        e.indexed( 7);
-        e.encode(output);
-        e.indexed( 5);
-        e.encode(output);
-        e.indexed(63);
-        e.encode(output);
-        e.literalWithIndexing("custom-key", false, "custom-value", false);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
-             "0c63 7573 746f 6d2d 7661 6c75 65",
-
-             "[  1] (s =  54) custom-key: custom-value\n" +
-             "[  2] (s =  53) cache-control: no-cache\n" +
-             "[  3] (s =  57) :authority: www.example.com\n" +
-             "      Table size: 164");
-        // @formatter:on
-    }
-
-    @Test
-    public void example5AllSplits() {
-
-        List<Consumer<Encoder>> actions = new LinkedList<>();
-        actions.add(e -> e.indexed(2));
-        actions.add(e -> e.indexed(6));
-        actions.add(e -> e.indexed(4));
-        actions.add(e -> e.literalWithIndexing(1, "www.example.com", false));
-
-        encodeAllSplits(
-                actions,
-
-                "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
-                "2e63 6f6d",
-
-                "[  1] (s =  57) :authority: www.example.com\n" +
-                "      Table size:  57");
-    }
-
-    private static void encodeAllSplits(Iterable<Consumer<Encoder>> consumers,
-                                        String expectedHexdump,
-                                        String expectedTableState) {
-        ByteBuffer buffer = SpecHelper.toBytes(expectedHexdump);
-        erase(buffer); // Zeroed buffer of size needed to hold the encoding
-        forEachSplit(buffer, iterable -> {
-            List<ByteBuffer> copy = new LinkedList<>();
-            iterable.forEach(b -> copy.add(ByteBuffer.allocate(b.remaining())));
-            Iterator<ByteBuffer> output = copy.iterator();
-            if (!output.hasNext()) {
-                throw new IllegalStateException("No buffers to encode to");
-            }
-            Encoder e = newCustomEncoder(256); // FIXME: pull up (as a parameter)
-            drainInitialUpdate(e);
-            boolean encoded;
-            ByteBuffer b = output.next();
-            for (Consumer<Encoder> c : consumers) {
-                c.accept(e);
-                do {
-                    encoded = e.encode(b);
-                    if (!encoded) {
-                        if (output.hasNext()) {
-                            b = output.next();
-                        } else {
-                            throw new IllegalStateException("No room for encoding");
-                        }
-                    }
-                }
-                while (!encoded);
-            }
-            copy.forEach(Buffer::flip);
-            ByteBuffer data = concat(copy);
-            test(e, data, expectedHexdump, expectedTableState);
-        });
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.4
-    //
-    @Test
-    public void example6() {
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        ByteBuffer output = ByteBuffer.allocate(64);
-        e.indexed(2);
-        e.encode(output);
-        e.indexed(6);
-        e.encode(output);
-        e.indexed(4);
-        e.encode(output);
-        e.literalWithIndexing(1, "www.example.com", true);
-        e.encode(output);
-
-        output.flip();
-
-        // @formatter:off
-        test(e, output,
-
-             "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
-             "ff",
-
-             "[  1] (s =  57) :authority: www.example.com\n" +
-             "      Table size:  57");
-
-        output.clear();
-
-        e.indexed( 2);
-        e.encode(output);
-        e.indexed( 6);
-        e.encode(output);
-        e.indexed( 4);
-        e.encode(output);
-        e.indexed(62);
-        e.encode(output);
-        e.literalWithIndexing(24, "no-cache", true);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "8286 84be 5886 a8eb 1064 9cbf",
-
-             "[  1] (s =  53) cache-control: no-cache\n" +
-             "[  2] (s =  57) :authority: www.example.com\n" +
-             "      Table size: 110");
-
-        output.clear();
-
-        e.indexed( 2);
-        e.encode(output);
-        e.indexed( 7);
-        e.encode(output);
-        e.indexed( 5);
-        e.encode(output);
-        e.indexed(63);
-        e.encode(output);
-        e.literalWithIndexing("custom-key", true, "custom-value", true);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
-             "a849 e95b b8e8 b4bf",
-
-             "[  1] (s =  54) custom-key: custom-value\n" +
-             "[  2] (s =  53) cache-control: no-cache\n" +
-             "[  3] (s =  57) :authority: www.example.com\n" +
-             "      Table size: 164");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.5
-    //
-    @Test
-    public void example7() {
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        ByteBuffer output = ByteBuffer.allocate(128);
-        // @formatter:off
-        e.literalWithIndexing( 8, "302", false);
-        e.encode(output);
-        e.literalWithIndexing(24, "private", false);
-        e.encode(output);
-        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", false);
-        e.encode(output);
-        e.literalWithIndexing(46, "https://www.example.com", false);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "4803 3330 3258 0770 7269 7661 7465 611d\n" +
-             "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
-             "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
-             "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
-             "6c65 2e63 6f6d",
-
-             "[  1] (s =  63) location: https://www.example.com\n" +
-             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-             "[  3] (s =  52) cache-control: private\n" +
-             "[  4] (s =  42) :status: 302\n" +
-             "      Table size: 222");
-
-        output.clear();
-
-        e.literalWithIndexing( 8, "307", false);
-        e.encode(output);
-        e.indexed(65);
-        e.encode(output);
-        e.indexed(64);
-        e.encode(output);
-        e.indexed(63);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "4803 3330 37c1 c0bf",
-
-             "[  1] (s =  42) :status: 307\n" +
-             "[  2] (s =  63) location: https://www.example.com\n" +
-             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-             "[  4] (s =  52) cache-control: private\n" +
-             "      Table size: 222");
-
-        output.clear();
-
-        e.indexed( 8);
-        e.encode(output);
-        e.indexed(65);
-        e.encode(output);
-        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", false);
-        e.encode(output);
-        e.indexed(64);
-        e.encode(output);
-        e.literalWithIndexing(26, "gzip", false);
-        e.encode(output);
-        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
-             "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
-             "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
-             "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
-             "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
-             "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
-             "3d31",
-
-             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
-             "[  2] (s =  52) content-encoding: gzip\n" +
-             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
-             "      Table size: 215");
-        // @formatter:on
-    }
-
-    //
-    // http://tools.ietf.org/html/rfc7541#appendix-C.6
-    //
-    @Test
-    public void example8() {
-        Encoder e = newCustomEncoder(256);
-        drainInitialUpdate(e);
-
-        ByteBuffer output = ByteBuffer.allocate(128);
-        // @formatter:off
-        e.literalWithIndexing( 8, "302", true);
-        e.encode(output);
-        e.literalWithIndexing(24, "private", true);
-        e.encode(output);
-        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", true);
-        e.encode(output);
-        e.literalWithIndexing(46, "https://www.example.com", true);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
-             "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
-             "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
-             "e9ae 82ae 43d3",
-
-             "[  1] (s =  63) location: https://www.example.com\n" +
-             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-             "[  3] (s =  52) cache-control: private\n" +
-             "[  4] (s =  42) :status: 302\n" +
-             "      Table size: 222");
-
-        output.clear();
-
-        e.literalWithIndexing( 8, "307", true);
-        e.encode(output);
-        e.indexed(65);
-        e.encode(output);
-        e.indexed(64);
-        e.encode(output);
-        e.indexed(63);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "4883 640e ffc1 c0bf",
-
-             "[  1] (s =  42) :status: 307\n" +
-             "[  2] (s =  63) location: https://www.example.com\n" +
-             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
-             "[  4] (s =  52) cache-control: private\n" +
-             "      Table size: 222");
-
-        output.clear();
-
-        e.indexed( 8);
-        e.encode(output);
-        e.indexed(65);
-        e.encode(output);
-        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", true);
-        e.encode(output);
-        e.indexed(64);
-        e.encode(output);
-        e.literalWithIndexing(26, "gzip", true);
-        e.encode(output);
-        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", true);
-        e.encode(output);
-
-        output.flip();
-
-        test(e, output,
-
-             "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
-             "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
-             "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
-             "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
-             "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
-
-             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
-             "[  2] (s =  52) content-encoding: gzip\n" +
-             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
-             "      Table size: 215");
-        // @formatter:on
-    }
-
-    @Test
-    public void initialSizeUpdateDefaultEncoder() {
-        Function<Integer, Encoder> e = Encoder::new;
-        testSizeUpdate(e, 1024, asList(), asList(0));
-        testSizeUpdate(e, 1024, asList(1024), asList(0));
-        testSizeUpdate(e, 1024, asList(1024, 1024), asList(0));
-        testSizeUpdate(e, 1024, asList(1024, 512), asList(0));
-        testSizeUpdate(e, 1024, asList(512, 1024), asList(0));
-        testSizeUpdate(e, 1024, asList(512, 2048), asList(0));
-    }
-
-    @Test
-    public void initialSizeUpdateCustomEncoder() {
-        Function<Integer, Encoder> e = EncoderTest::newCustomEncoder;
-        testSizeUpdate(e, 1024, asList(), asList(1024));
-        testSizeUpdate(e, 1024, asList(1024), asList(1024));
-        testSizeUpdate(e, 1024, asList(1024, 1024), asList(1024));
-        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
-        testSizeUpdate(e, 1024, asList(512, 1024), asList(1024));
-        testSizeUpdate(e, 1024, asList(512, 2048), asList(2048));
-    }
-
-    @Test
-    public void seriesOfSizeUpdatesDefaultEncoder() {
-        Function<Integer, Encoder> e = c -> {
-            Encoder encoder = new Encoder(c);
-            drainInitialUpdate(encoder);
-            return encoder;
-        };
-        testSizeUpdate(e, 0, asList(0), asList());
-        testSizeUpdate(e, 1024, asList(1024), asList());
-        testSizeUpdate(e, 1024, asList(2048), asList());
-        testSizeUpdate(e, 1024, asList(512), asList());
-        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
-        testSizeUpdate(e, 1024, asList(1024, 2048), asList());
-        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
-        testSizeUpdate(e, 1024, asList(1024, 512), asList());
-        testSizeUpdate(e, 1024, asList(512, 1024), asList());
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#section-4.2
-    //
-    @Test
-    public void seriesOfSizeUpdatesCustomEncoder() {
-        Function<Integer, Encoder> e = c -> {
-            Encoder encoder = newCustomEncoder(c);
-            drainInitialUpdate(encoder);
-            return encoder;
-        };
-        testSizeUpdate(e, 0, asList(0), asList());
-        testSizeUpdate(e, 1024, asList(1024), asList());
-        testSizeUpdate(e, 1024, asList(2048), asList(2048));
-        testSizeUpdate(e, 1024, asList(512), asList(512));
-        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
-        testSizeUpdate(e, 1024, asList(1024, 2048), asList(2048));
-        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
-        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
-        testSizeUpdate(e, 1024, asList(512, 1024), asList(512, 1024));
-    }
-
-    @Test
-    public void callSequenceViolations() {
-        {   // Hasn't set up a header
-            Encoder e = new Encoder(0);
-            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
-        }
-        {   // Can't set up header while there's an unfinished encoding
-            Encoder e = new Encoder(0);
-            e.indexed(32);
-            assertVoidThrows(IllegalStateException.class, () -> e.indexed(32));
-        }
-        {   // Can't setMaxCapacity while there's an unfinished encoding
-            Encoder e = new Encoder(0);
-            e.indexed(32);
-            assertVoidThrows(IllegalStateException.class, () -> e.setMaxCapacity(512));
-        }
-        {   // Hasn't set up a header
-            Encoder e = new Encoder(0);
-            e.setMaxCapacity(256);
-            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
-        }
-        {   // Hasn't set up a header after the previous encoding
-            Encoder e = new Encoder(0);
-            e.indexed(0);
-            boolean encoded = e.encode(ByteBuffer.allocate(16));
-            assertTrue(encoded); // assumption
-            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
-        }
-    }
-
-    private static void test(Encoder encoder,
-                             String expectedTableState,
-                             String expectedHexdump) {
-
-        ByteBuffer b = ByteBuffer.allocate(128);
-        encoder.encode(b);
-        b.flip();
-        test(encoder, b, expectedTableState, expectedHexdump);
-    }
-
-    private static void test(Encoder encoder,
-                             ByteBuffer output,
-                             String expectedHexdump,
-                             String expectedTableState) {
-
-        String actualTableState = encoder.getHeaderTable().getStateString();
-        assertEquals(actualTableState, expectedTableState);
-
-        String actualHexdump = toHexdump(output);
-        assertEquals(actualHexdump, expectedHexdump.replaceAll("\\n", " "));
-    }
-
-    // initial size - the size encoder is constructed with
-    // updates      - a sequence of values for consecutive calls to encoder.setMaxCapacity
-    // expected     - a sequence of values expected to be decoded by a decoder
-    private void testSizeUpdate(Function<Integer, Encoder> encoder,
-                                int initialSize,
-                                List<Integer> updates,
-                                List<Integer> expected) {
-        Encoder e = encoder.apply(initialSize);
-        updates.forEach(e::setMaxCapacity);
-        ByteBuffer b = ByteBuffer.allocate(64);
-        e.header("a", "b");
-        e.encode(b);
-        b.flip();
-        Decoder d = new Decoder(updates.isEmpty() ? initialSize : Collections.max(updates));
-        List<Integer> actual = new ArrayList<>();
-        d.decode(b, true, new DecodingCallback() {
-            @Override
-            public void onDecoded(CharSequence name, CharSequence value) { }
-
-            @Override
-            public void onSizeUpdate(int capacity) {
-                actual.add(capacity);
-            }
-        });
-        assertEquals(actual, expected);
-    }
-
-    //
-    // Default encoder does not need any table, therefore a subclass that
-    // behaves differently is needed
-    //
-    private static Encoder newCustomEncoder(int maxCapacity) {
-        return new Encoder(maxCapacity) {
-            @Override
-            protected int calculateCapacity(int maxCapacity) {
-                return maxCapacity;
-            }
-        };
-    }
-
-    private static void drainInitialUpdate(Encoder e) {
-        ByteBuffer b = ByteBuffer.allocate(4);
-        e.header("a", "b");
-        boolean done;
-        do {
-            done = e.encode(b);
-            b.flip();
-        } while (!done);
-    }
-
-    private static void erase(ByteBuffer buffer) {
-        buffer.clear();
-        while (buffer.hasRemaining()) {
-            buffer.put((byte) 0);
-        }
-        buffer.clear();
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HeaderTableTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.Test;
-import sun.net.httpclient.hpack.HeaderTable.HeaderField;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static java.lang.String.format;
-import static org.testng.Assert.assertEquals;
-import static sun.net.httpclient.hpack.TestHelper.assertExceptionMessageContains;
-import static sun.net.httpclient.hpack.TestHelper.assertThrows;
-import static sun.net.httpclient.hpack.TestHelper.assertVoidThrows;
-import static sun.net.httpclient.hpack.TestHelper.newRandom;
-
-public class HeaderTableTest {
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-A
-    //
-    // @formatter:off
-    private static final String SPEC =
-       "          | 1     | :authority                  |               |\n" +
-       "          | 2     | :method                     | GET           |\n" +
-       "          | 3     | :method                     | POST          |\n" +
-       "          | 4     | :path                       | /             |\n" +
-       "          | 5     | :path                       | /index.html   |\n" +
-       "          | 6     | :scheme                     | http          |\n" +
-       "          | 7     | :scheme                     | https         |\n" +
-       "          | 8     | :status                     | 200           |\n" +
-       "          | 9     | :status                     | 204           |\n" +
-       "          | 10    | :status                     | 206           |\n" +
-       "          | 11    | :status                     | 304           |\n" +
-       "          | 12    | :status                     | 400           |\n" +
-       "          | 13    | :status                     | 404           |\n" +
-       "          | 14    | :status                     | 500           |\n" +
-       "          | 15    | accept-charset              |               |\n" +
-       "          | 16    | accept-encoding             | gzip, deflate |\n" +
-       "          | 17    | accept-language             |               |\n" +
-       "          | 18    | accept-ranges               |               |\n" +
-       "          | 19    | accept                      |               |\n" +
-       "          | 20    | access-control-allow-origin |               |\n" +
-       "          | 21    | age                         |               |\n" +
-       "          | 22    | allow                       |               |\n" +
-       "          | 23    | authorization               |               |\n" +
-       "          | 24    | cache-control               |               |\n" +
-       "          | 25    | content-disposition         |               |\n" +
-       "          | 26    | content-encoding            |               |\n" +
-       "          | 27    | content-language            |               |\n" +
-       "          | 28    | content-length              |               |\n" +
-       "          | 29    | content-location            |               |\n" +
-       "          | 30    | content-range               |               |\n" +
-       "          | 31    | content-type                |               |\n" +
-       "          | 32    | cookie                      |               |\n" +
-       "          | 33    | date                        |               |\n" +
-       "          | 34    | etag                        |               |\n" +
-       "          | 35    | expect                      |               |\n" +
-       "          | 36    | expires                     |               |\n" +
-       "          | 37    | from                        |               |\n" +
-       "          | 38    | host                        |               |\n" +
-       "          | 39    | if-match                    |               |\n" +
-       "          | 40    | if-modified-since           |               |\n" +
-       "          | 41    | if-none-match               |               |\n" +
-       "          | 42    | if-range                    |               |\n" +
-       "          | 43    | if-unmodified-since         |               |\n" +
-       "          | 44    | last-modified               |               |\n" +
-       "          | 45    | link                        |               |\n" +
-       "          | 46    | location                    |               |\n" +
-       "          | 47    | max-forwards                |               |\n" +
-       "          | 48    | proxy-authenticate          |               |\n" +
-       "          | 49    | proxy-authorization         |               |\n" +
-       "          | 50    | range                       |               |\n" +
-       "          | 51    | referer                     |               |\n" +
-       "          | 52    | refresh                     |               |\n" +
-       "          | 53    | retry-after                 |               |\n" +
-       "          | 54    | server                      |               |\n" +
-       "          | 55    | set-cookie                  |               |\n" +
-       "          | 56    | strict-transport-security   |               |\n" +
-       "          | 57    | transfer-encoding           |               |\n" +
-       "          | 58    | user-agent                  |               |\n" +
-       "          | 59    | vary                        |               |\n" +
-       "          | 60    | via                         |               |\n" +
-       "          | 61    | www-authenticate            |               |\n";
-    // @formatter:on
-
-    private static final int STATIC_TABLE_LENGTH = createStaticEntries().size();
-    private final Random rnd = newRandom();
-
-    @Test
-    public void staticData() {
-        HeaderTable table = new HeaderTable(0);
-        Map<Integer, HeaderField> staticHeaderFields = createStaticEntries();
-
-        Map<String, Integer> minimalIndexes = new HashMap<>();
-
-        for (Map.Entry<Integer, HeaderField> e : staticHeaderFields.entrySet()) {
-            Integer idx = e.getKey();
-            String hName = e.getValue().name;
-            Integer midx = minimalIndexes.get(hName);
-            if (midx == null) {
-                minimalIndexes.put(hName, idx);
-            } else {
-                minimalIndexes.put(hName, Math.min(idx, midx));
-            }
-        }
-
-        staticHeaderFields.entrySet().forEach(
-                e -> {
-                    // lookup
-                    HeaderField actualHeaderField = table.get(e.getKey());
-                    HeaderField expectedHeaderField = e.getValue();
-                    assertEquals(actualHeaderField, expectedHeaderField);
-
-                    // reverse lookup (name, value)
-                    String hName = expectedHeaderField.name;
-                    String hValue = expectedHeaderField.value;
-                    int expectedIndex = e.getKey();
-                    int actualIndex = table.indexOf(hName, hValue);
-
-                    assertEquals(actualIndex, expectedIndex);
-
-                    // reverse lookup (name)
-                    int expectedMinimalIndex = minimalIndexes.get(hName);
-                    int actualMinimalIndex = table.indexOf(hName, "blah-blah");
-
-                    assertEquals(-actualMinimalIndex, expectedMinimalIndex);
-                }
-        );
-    }
-
-    @Test
-    public void constructorSetsMaxSize() {
-        int size = rnd.nextInt(64);
-        HeaderTable t = new HeaderTable(size);
-        assertEquals(t.size(), 0);
-        assertEquals(t.maxSize(), size);
-    }
-
-    @Test
-    public void negativeMaximumSize() {
-        int maxSize = -(rnd.nextInt(100) + 1); // [-100, -1]
-        IllegalArgumentException e =
-                assertVoidThrows(IllegalArgumentException.class,
-                        () -> new HeaderTable(0).setMaxSize(maxSize));
-        assertExceptionMessageContains(e, "maxSize");
-    }
-
-    @Test
-    public void zeroMaximumSize() {
-        HeaderTable table = new HeaderTable(0);
-        table.setMaxSize(0);
-        assertEquals(table.maxSize(), 0);
-    }
-
-    @Test
-    public void negativeIndex() {
-        int idx = -(rnd.nextInt(256) + 1); // [-256, -1]
-        IllegalArgumentException e =
-                assertVoidThrows(IllegalArgumentException.class,
-                        () -> new HeaderTable(0).get(idx));
-        assertExceptionMessageContains(e, "index");
-    }
-
-    @Test
-    public void zeroIndex() {
-        IllegalArgumentException e =
-                assertThrows(IllegalArgumentException.class,
-                        () -> new HeaderTable(0).get(0));
-        assertExceptionMessageContains(e, "index");
-    }
-
-    @Test
-    public void length() {
-        HeaderTable table = new HeaderTable(0);
-        assertEquals(table.length(), STATIC_TABLE_LENGTH);
-    }
-
-    @Test
-    public void indexOutsideStaticRange() {
-        HeaderTable table = new HeaderTable(0);
-        int idx = table.length() + (rnd.nextInt(256) + 1);
-        IllegalArgumentException e =
-                assertThrows(IllegalArgumentException.class,
-                        () -> table.get(idx));
-        assertExceptionMessageContains(e, "index");
-    }
-
-    @Test
-    public void entryPutAfterStaticArea() {
-        HeaderTable table = new HeaderTable(256);
-        int idx = table.length() + 1;
-        assertThrows(IllegalArgumentException.class, () -> table.get(idx));
-
-        byte[] bytes = new byte[32];
-        rnd.nextBytes(bytes);
-        String name = new String(bytes, StandardCharsets.ISO_8859_1);
-        String value = "custom-value";
-
-        table.put(name, value);
-        HeaderField f = table.get(idx);
-        assertEquals(name, f.name);
-        assertEquals(value, f.value);
-    }
-
-    @Test
-    public void staticTableHasZeroSize() {
-        HeaderTable table = new HeaderTable(0);
-        assertEquals(0, table.size());
-    }
-
-    @Test
-    public void lowerIndexPriority() {
-        HeaderTable table = new HeaderTable(256);
-        int oldLength = table.length();
-        table.put("bender", "rodriguez");
-        table.put("bender", "rodriguez");
-        table.put("bender", "rodriguez");
-
-        assertEquals(table.length(), oldLength + 3); // more like an assumption
-        int i = table.indexOf("bender", "rodriguez");
-        assertEquals(oldLength + 1, i);
-    }
-
-    @Test
-    public void lowerIndexPriority2() {
-        HeaderTable table = new HeaderTable(256);
-        int oldLength = table.length();
-        int idx = rnd.nextInt(oldLength) + 1;
-        HeaderField f = table.get(idx);
-        table.put(f.name, f.value);
-        assertEquals(table.length(), oldLength + 1);
-        int i = table.indexOf(f.name, f.value);
-        assertEquals(idx, i);
-    }
-
-    // TODO: negative indexes check
-    // TODO: ensure full table clearance when adding huge header field
-    // TODO: ensure eviction deletes minimum needed entries, not more
-
-    @Test
-    public void fifo() {
-        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
-        // Let's add a series of header fields
-        int NUM_HEADERS = 32;
-        for (int i = 1; i <= NUM_HEADERS; i++) {
-            String s = String.valueOf(i);
-            t.put(s, s);
-        }
-        // They MUST appear in a FIFO order:
-        //   newer entries are at lower indexes
-        //   older entries are at higher indexes
-        for (int j = 1; j <= NUM_HEADERS; j++) {
-            HeaderField f = t.get(STATIC_TABLE_LENGTH + j);
-            int actualName = Integer.parseInt(f.name);
-            int expectedName = NUM_HEADERS - j + 1;
-            assertEquals(expectedName, actualName);
-        }
-        // Entries MUST be evicted in the order they were added:
-        //   the newer the entry the later it is evicted
-        for (int k = 1; k <= NUM_HEADERS; k++) {
-            HeaderField f = t.evictEntry();
-            assertEquals(String.valueOf(k), f.name);
-        }
-    }
-
-    @Test
-    public void indexOf() {
-        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
-        // Let's put a series of header fields
-        int NUM_HEADERS = 32;
-        for (int i = 1; i <= NUM_HEADERS; i++) {
-            String s = String.valueOf(i);
-            t.put(s, s);
-        }
-        // and verify indexOf (reverse lookup) returns correct indexes for
-        // full lookup
-        for (int j = 1; j <= NUM_HEADERS; j++) {
-            String s = String.valueOf(j);
-            int actualIndex = t.indexOf(s, s);
-            int expectedIndex = STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1;
-            assertEquals(expectedIndex, actualIndex);
-        }
-        // as well as for just a name lookup
-        for (int j = 1; j <= NUM_HEADERS; j++) {
-            String s = String.valueOf(j);
-            int actualIndex = t.indexOf(s, "blah");
-            int expectedIndex = -(STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1);
-            assertEquals(expectedIndex, actualIndex);
-        }
-        // lookup for non-existent name returns 0
-        assertEquals(0, t.indexOf("chupacabra", "1"));
-    }
-
-    @Test
-    public void testToString() {
-        testToString0();
-    }
-
-    @Test
-    public void testToStringDifferentLocale() {
-        Locale.setDefault(Locale.FRENCH);
-        String s = format("%.1f", 3.1);
-        assertEquals("3,1", s); // assumption of the test, otherwise the test is useless
-        testToString0();
-    }
-
-    private void testToString0() {
-        HeaderTable table = new HeaderTable(0);
-        {
-            table.setMaxSize(2048);
-            String expected =
-                    format("entries: %d; used %s/%s (%.1f%%)", 0, 0, 2048, 0.0);
-            assertEquals(expected, table.toString());
-        }
-
-        {
-            String name = "custom-name";
-            String value = "custom-value";
-            int size = 512;
-
-            table.setMaxSize(size);
-            table.put(name, value);
-            String s = table.toString();
-
-            int used = name.length() + value.length() + 32;
-            double ratio = used * 100.0 / size;
-
-            String expected =
-                    format("entries: 1; used %s/%s (%.1f%%)", used, size, ratio);
-            assertEquals(expected, s);
-        }
-
-        {
-            table.setMaxSize(78);
-            table.put(":method", "");
-            table.put(":status", "");
-            String s = table.toString();
-            String expected =
-                    format("entries: %d; used %s/%s (%.1f%%)", 2, 78, 78, 100.0);
-            assertEquals(expected, s);
-        }
-    }
-
-    @Test
-    public void stateString() {
-        HeaderTable table = new HeaderTable(256);
-        table.put("custom-key", "custom-header");
-        // @formatter:off
-        assertEquals("[  1] (s =  55) custom-key: custom-header\n" +
-                     "      Table size:  55", table.getStateString());
-        // @formatter:on
-    }
-
-    private static Map<Integer, HeaderField> createStaticEntries() {
-        Pattern line = Pattern.compile(
-                "\\|\\s*(?<index>\\d+?)\\s*\\|\\s*(?<name>.+?)\\s*\\|\\s*(?<value>.*?)\\s*\\|");
-        Matcher m = line.matcher(SPEC);
-        Map<Integer, HeaderField> result = new HashMap<>();
-        while (m.find()) {
-            int index = Integer.parseInt(m.group("index"));
-            String name = m.group("name");
-            String value = m.group("value");
-            HeaderField f = new HeaderField(name, value);
-            result.put(index, f);
-        }
-        return Collections.unmodifiableMap(result); // lol
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HuffmanTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,623 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Stack;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static java.lang.Integer.parseInt;
-import static org.testng.Assert.*;
-
-public final class HuffmanTest {
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-B
-    //
-    private static final String SPEC =
-            // @formatter:off
-     "                          code as bits                 as hex   len\n" +
-     "        sym              aligned to MSB                aligned   in\n" +
-     "                                                       to LSB   bits\n" +
-     "       (  0)  |11111111|11000                             1ff8  [13]\n" +
-     "       (  1)  |11111111|11111111|1011000                7fffd8  [23]\n" +
-     "       (  2)  |11111111|11111111|11111110|0010         fffffe2  [28]\n" +
-     "       (  3)  |11111111|11111111|11111110|0011         fffffe3  [28]\n" +
-     "       (  4)  |11111111|11111111|11111110|0100         fffffe4  [28]\n" +
-     "       (  5)  |11111111|11111111|11111110|0101         fffffe5  [28]\n" +
-     "       (  6)  |11111111|11111111|11111110|0110         fffffe6  [28]\n" +
-     "       (  7)  |11111111|11111111|11111110|0111         fffffe7  [28]\n" +
-     "       (  8)  |11111111|11111111|11111110|1000         fffffe8  [28]\n" +
-     "       (  9)  |11111111|11111111|11101010               ffffea  [24]\n" +
-     "       ( 10)  |11111111|11111111|11111111|111100      3ffffffc  [30]\n" +
-     "       ( 11)  |11111111|11111111|11111110|1001         fffffe9  [28]\n" +
-     "       ( 12)  |11111111|11111111|11111110|1010         fffffea  [28]\n" +
-     "       ( 13)  |11111111|11111111|11111111|111101      3ffffffd  [30]\n" +
-     "       ( 14)  |11111111|11111111|11111110|1011         fffffeb  [28]\n" +
-     "       ( 15)  |11111111|11111111|11111110|1100         fffffec  [28]\n" +
-     "       ( 16)  |11111111|11111111|11111110|1101         fffffed  [28]\n" +
-     "       ( 17)  |11111111|11111111|11111110|1110         fffffee  [28]\n" +
-     "       ( 18)  |11111111|11111111|11111110|1111         fffffef  [28]\n" +
-     "       ( 19)  |11111111|11111111|11111111|0000         ffffff0  [28]\n" +
-     "       ( 20)  |11111111|11111111|11111111|0001         ffffff1  [28]\n" +
-     "       ( 21)  |11111111|11111111|11111111|0010         ffffff2  [28]\n" +
-     "       ( 22)  |11111111|11111111|11111111|111110      3ffffffe  [30]\n" +
-     "       ( 23)  |11111111|11111111|11111111|0011         ffffff3  [28]\n" +
-     "       ( 24)  |11111111|11111111|11111111|0100         ffffff4  [28]\n" +
-     "       ( 25)  |11111111|11111111|11111111|0101         ffffff5  [28]\n" +
-     "       ( 26)  |11111111|11111111|11111111|0110         ffffff6  [28]\n" +
-     "       ( 27)  |11111111|11111111|11111111|0111         ffffff7  [28]\n" +
-     "       ( 28)  |11111111|11111111|11111111|1000         ffffff8  [28]\n" +
-     "       ( 29)  |11111111|11111111|11111111|1001         ffffff9  [28]\n" +
-     "       ( 30)  |11111111|11111111|11111111|1010         ffffffa  [28]\n" +
-     "       ( 31)  |11111111|11111111|11111111|1011         ffffffb  [28]\n" +
-     "   ' ' ( 32)  |010100                                       14  [ 6]\n" +
-     "   '!' ( 33)  |11111110|00                                 3f8  [10]\n" +
-     "  '\"' ( 34)  |11111110|01                                 3f9  [10]\n" +
-     "   '#' ( 35)  |11111111|1010                               ffa  [12]\n" +
-     "   '$' ( 36)  |11111111|11001                             1ff9  [13]\n" +
-     "   '%' ( 37)  |010101                                       15  [ 6]\n" +
-     "   '&' ( 38)  |11111000                                     f8  [ 8]\n" +
-     "   ''' ( 39)  |11111111|010                                7fa  [11]\n" +
-     "   '(' ( 40)  |11111110|10                                 3fa  [10]\n" +
-     "   ')' ( 41)  |11111110|11                                 3fb  [10]\n" +
-     "   '*' ( 42)  |11111001                                     f9  [ 8]\n" +
-     "   '+' ( 43)  |11111111|011                                7fb  [11]\n" +
-     "   ',' ( 44)  |11111010                                     fa  [ 8]\n" +
-     "   '-' ( 45)  |010110                                       16  [ 6]\n" +
-     "   '.' ( 46)  |010111                                       17  [ 6]\n" +
-     "   '/' ( 47)  |011000                                       18  [ 6]\n" +
-     "   '0' ( 48)  |00000                                         0  [ 5]\n" +
-     "   '1' ( 49)  |00001                                         1  [ 5]\n" +
-     "   '2' ( 50)  |00010                                         2  [ 5]\n" +
-     "   '3' ( 51)  |011001                                       19  [ 6]\n" +
-     "   '4' ( 52)  |011010                                       1a  [ 6]\n" +
-     "   '5' ( 53)  |011011                                       1b  [ 6]\n" +
-     "   '6' ( 54)  |011100                                       1c  [ 6]\n" +
-     "   '7' ( 55)  |011101                                       1d  [ 6]\n" +
-     "   '8' ( 56)  |011110                                       1e  [ 6]\n" +
-     "   '9' ( 57)  |011111                                       1f  [ 6]\n" +
-     "   ':' ( 58)  |1011100                                      5c  [ 7]\n" +
-     "   ';' ( 59)  |11111011                                     fb  [ 8]\n" +
-     "   '<' ( 60)  |11111111|1111100                           7ffc  [15]\n" +
-     "   '=' ( 61)  |100000                                       20  [ 6]\n" +
-     "   '>' ( 62)  |11111111|1011                               ffb  [12]\n" +
-     "   '?' ( 63)  |11111111|00                                 3fc  [10]\n" +
-     "   '@' ( 64)  |11111111|11010                             1ffa  [13]\n" +
-     "   'A' ( 65)  |100001                                       21  [ 6]\n" +
-     "   'B' ( 66)  |1011101                                      5d  [ 7]\n" +
-     "   'C' ( 67)  |1011110                                      5e  [ 7]\n" +
-     "   'D' ( 68)  |1011111                                      5f  [ 7]\n" +
-     "   'E' ( 69)  |1100000                                      60  [ 7]\n" +
-     "   'F' ( 70)  |1100001                                      61  [ 7]\n" +
-     "   'G' ( 71)  |1100010                                      62  [ 7]\n" +
-     "   'H' ( 72)  |1100011                                      63  [ 7]\n" +
-     "   'I' ( 73)  |1100100                                      64  [ 7]\n" +
-     "   'J' ( 74)  |1100101                                      65  [ 7]\n" +
-     "   'K' ( 75)  |1100110                                      66  [ 7]\n" +
-     "   'L' ( 76)  |1100111                                      67  [ 7]\n" +
-     "   'M' ( 77)  |1101000                                      68  [ 7]\n" +
-     "   'N' ( 78)  |1101001                                      69  [ 7]\n" +
-     "   'O' ( 79)  |1101010                                      6a  [ 7]\n" +
-     "   'P' ( 80)  |1101011                                      6b  [ 7]\n" +
-     "   'Q' ( 81)  |1101100                                      6c  [ 7]\n" +
-     "   'R' ( 82)  |1101101                                      6d  [ 7]\n" +
-     "   'S' ( 83)  |1101110                                      6e  [ 7]\n" +
-     "   'T' ( 84)  |1101111                                      6f  [ 7]\n" +
-     "   'U' ( 85)  |1110000                                      70  [ 7]\n" +
-     "   'V' ( 86)  |1110001                                      71  [ 7]\n" +
-     "   'W' ( 87)  |1110010                                      72  [ 7]\n" +
-     "   'X' ( 88)  |11111100                                     fc  [ 8]\n" +
-     "   'Y' ( 89)  |1110011                                      73  [ 7]\n" +
-     "   'Z' ( 90)  |11111101                                     fd  [ 8]\n" +
-     "   '[' ( 91)  |11111111|11011                             1ffb  [13]\n" +
-     "  '\\' ( 92)  |11111111|11111110|000                     7fff0  [19]\n" +
-     "   ']' ( 93)  |11111111|11100                             1ffc  [13]\n" +
-     "   '^' ( 94)  |11111111|111100                            3ffc  [14]\n" +
-     "   '_' ( 95)  |100010                                       22  [ 6]\n" +
-     "   '`' ( 96)  |11111111|1111101                           7ffd  [15]\n" +
-     "   'a' ( 97)  |00011                                         3  [ 5]\n" +
-     "   'b' ( 98)  |100011                                       23  [ 6]\n" +
-     "   'c' ( 99)  |00100                                         4  [ 5]\n" +
-     "   'd' (100)  |100100                                       24  [ 6]\n" +
-     "   'e' (101)  |00101                                         5  [ 5]\n" +
-     "   'f' (102)  |100101                                       25  [ 6]\n" +
-     "   'g' (103)  |100110                                       26  [ 6]\n" +
-     "   'h' (104)  |100111                                       27  [ 6]\n" +
-     "   'i' (105)  |00110                                         6  [ 5]\n" +
-     "   'j' (106)  |1110100                                      74  [ 7]\n" +
-     "   'k' (107)  |1110101                                      75  [ 7]\n" +
-     "   'l' (108)  |101000                                       28  [ 6]\n" +
-     "   'm' (109)  |101001                                       29  [ 6]\n" +
-     "   'n' (110)  |101010                                       2a  [ 6]\n" +
-     "   'o' (111)  |00111                                         7  [ 5]\n" +
-     "   'p' (112)  |101011                                       2b  [ 6]\n" +
-     "   'q' (113)  |1110110                                      76  [ 7]\n" +
-     "   'r' (114)  |101100                                       2c  [ 6]\n" +
-     "   's' (115)  |01000                                         8  [ 5]\n" +
-     "   't' (116)  |01001                                         9  [ 5]\n" +
-     "   'u' (117)  |101101                                       2d  [ 6]\n" +
-     "   'v' (118)  |1110111                                      77  [ 7]\n" +
-     "   'w' (119)  |1111000                                      78  [ 7]\n" +
-     "   'x' (120)  |1111001                                      79  [ 7]\n" +
-     "   'y' (121)  |1111010                                      7a  [ 7]\n" +
-     "   'z' (122)  |1111011                                      7b  [ 7]\n" +
-     "   '{' (123)  |11111111|1111110                           7ffe  [15]\n" +
-     "   '|' (124)  |11111111|100                                7fc  [11]\n" +
-     "   '}' (125)  |11111111|111101                            3ffd  [14]\n" +
-     "   '~' (126)  |11111111|11101                             1ffd  [13]\n" +
-     "       (127)  |11111111|11111111|11111111|1100         ffffffc  [28]\n" +
-     "       (128)  |11111111|11111110|0110                    fffe6  [20]\n" +
-     "       (129)  |11111111|11111111|010010                 3fffd2  [22]\n" +
-     "       (130)  |11111111|11111110|0111                    fffe7  [20]\n" +
-     "       (131)  |11111111|11111110|1000                    fffe8  [20]\n" +
-     "       (132)  |11111111|11111111|010011                 3fffd3  [22]\n" +
-     "       (133)  |11111111|11111111|010100                 3fffd4  [22]\n" +
-     "       (134)  |11111111|11111111|010101                 3fffd5  [22]\n" +
-     "       (135)  |11111111|11111111|1011001                7fffd9  [23]\n" +
-     "       (136)  |11111111|11111111|010110                 3fffd6  [22]\n" +
-     "       (137)  |11111111|11111111|1011010                7fffda  [23]\n" +
-     "       (138)  |11111111|11111111|1011011                7fffdb  [23]\n" +
-     "       (139)  |11111111|11111111|1011100                7fffdc  [23]\n" +
-     "       (140)  |11111111|11111111|1011101                7fffdd  [23]\n" +
-     "       (141)  |11111111|11111111|1011110                7fffde  [23]\n" +
-     "       (142)  |11111111|11111111|11101011               ffffeb  [24]\n" +
-     "       (143)  |11111111|11111111|1011111                7fffdf  [23]\n" +
-     "       (144)  |11111111|11111111|11101100               ffffec  [24]\n" +
-     "       (145)  |11111111|11111111|11101101               ffffed  [24]\n" +
-     "       (146)  |11111111|11111111|010111                 3fffd7  [22]\n" +
-     "       (147)  |11111111|11111111|1100000                7fffe0  [23]\n" +
-     "       (148)  |11111111|11111111|11101110               ffffee  [24]\n" +
-     "       (149)  |11111111|11111111|1100001                7fffe1  [23]\n" +
-     "       (150)  |11111111|11111111|1100010                7fffe2  [23]\n" +
-     "       (151)  |11111111|11111111|1100011                7fffe3  [23]\n" +
-     "       (152)  |11111111|11111111|1100100                7fffe4  [23]\n" +
-     "       (153)  |11111111|11111110|11100                  1fffdc  [21]\n" +
-     "       (154)  |11111111|11111111|011000                 3fffd8  [22]\n" +
-     "       (155)  |11111111|11111111|1100101                7fffe5  [23]\n" +
-     "       (156)  |11111111|11111111|011001                 3fffd9  [22]\n" +
-     "       (157)  |11111111|11111111|1100110                7fffe6  [23]\n" +
-     "       (158)  |11111111|11111111|1100111                7fffe7  [23]\n" +
-     "       (159)  |11111111|11111111|11101111               ffffef  [24]\n" +
-     "       (160)  |11111111|11111111|011010                 3fffda  [22]\n" +
-     "       (161)  |11111111|11111110|11101                  1fffdd  [21]\n" +
-     "       (162)  |11111111|11111110|1001                    fffe9  [20]\n" +
-     "       (163)  |11111111|11111111|011011                 3fffdb  [22]\n" +
-     "       (164)  |11111111|11111111|011100                 3fffdc  [22]\n" +
-     "       (165)  |11111111|11111111|1101000                7fffe8  [23]\n" +
-     "       (166)  |11111111|11111111|1101001                7fffe9  [23]\n" +
-     "       (167)  |11111111|11111110|11110                  1fffde  [21]\n" +
-     "       (168)  |11111111|11111111|1101010                7fffea  [23]\n" +
-     "       (169)  |11111111|11111111|011101                 3fffdd  [22]\n" +
-     "       (170)  |11111111|11111111|011110                 3fffde  [22]\n" +
-     "       (171)  |11111111|11111111|11110000               fffff0  [24]\n" +
-     "       (172)  |11111111|11111110|11111                  1fffdf  [21]\n" +
-     "       (173)  |11111111|11111111|011111                 3fffdf  [22]\n" +
-     "       (174)  |11111111|11111111|1101011                7fffeb  [23]\n" +
-     "       (175)  |11111111|11111111|1101100                7fffec  [23]\n" +
-     "       (176)  |11111111|11111111|00000                  1fffe0  [21]\n" +
-     "       (177)  |11111111|11111111|00001                  1fffe1  [21]\n" +
-     "       (178)  |11111111|11111111|100000                 3fffe0  [22]\n" +
-     "       (179)  |11111111|11111111|00010                  1fffe2  [21]\n" +
-     "       (180)  |11111111|11111111|1101101                7fffed  [23]\n" +
-     "       (181)  |11111111|11111111|100001                 3fffe1  [22]\n" +
-     "       (182)  |11111111|11111111|1101110                7fffee  [23]\n" +
-     "       (183)  |11111111|11111111|1101111                7fffef  [23]\n" +
-     "       (184)  |11111111|11111110|1010                    fffea  [20]\n" +
-     "       (185)  |11111111|11111111|100010                 3fffe2  [22]\n" +
-     "       (186)  |11111111|11111111|100011                 3fffe3  [22]\n" +
-     "       (187)  |11111111|11111111|100100                 3fffe4  [22]\n" +
-     "       (188)  |11111111|11111111|1110000                7ffff0  [23]\n" +
-     "       (189)  |11111111|11111111|100101                 3fffe5  [22]\n" +
-     "       (190)  |11111111|11111111|100110                 3fffe6  [22]\n" +
-     "       (191)  |11111111|11111111|1110001                7ffff1  [23]\n" +
-     "       (192)  |11111111|11111111|11111000|00           3ffffe0  [26]\n" +
-     "       (193)  |11111111|11111111|11111000|01           3ffffe1  [26]\n" +
-     "       (194)  |11111111|11111110|1011                    fffeb  [20]\n" +
-     "       (195)  |11111111|11111110|001                     7fff1  [19]\n" +
-     "       (196)  |11111111|11111111|100111                 3fffe7  [22]\n" +
-     "       (197)  |11111111|11111111|1110010                7ffff2  [23]\n" +
-     "       (198)  |11111111|11111111|101000                 3fffe8  [22]\n" +
-     "       (199)  |11111111|11111111|11110110|0            1ffffec  [25]\n" +
-     "       (200)  |11111111|11111111|11111000|10           3ffffe2  [26]\n" +
-     "       (201)  |11111111|11111111|11111000|11           3ffffe3  [26]\n" +
-     "       (202)  |11111111|11111111|11111001|00           3ffffe4  [26]\n" +
-     "       (203)  |11111111|11111111|11111011|110          7ffffde  [27]\n" +
-     "       (204)  |11111111|11111111|11111011|111          7ffffdf  [27]\n" +
-     "       (205)  |11111111|11111111|11111001|01           3ffffe5  [26]\n" +
-     "       (206)  |11111111|11111111|11110001               fffff1  [24]\n" +
-     "       (207)  |11111111|11111111|11110110|1            1ffffed  [25]\n" +
-     "       (208)  |11111111|11111110|010                     7fff2  [19]\n" +
-     "       (209)  |11111111|11111111|00011                  1fffe3  [21]\n" +
-     "       (210)  |11111111|11111111|11111001|10           3ffffe6  [26]\n" +
-     "       (211)  |11111111|11111111|11111100|000          7ffffe0  [27]\n" +
-     "       (212)  |11111111|11111111|11111100|001          7ffffe1  [27]\n" +
-     "       (213)  |11111111|11111111|11111001|11           3ffffe7  [26]\n" +
-     "       (214)  |11111111|11111111|11111100|010          7ffffe2  [27]\n" +
-     "       (215)  |11111111|11111111|11110010               fffff2  [24]\n" +
-     "       (216)  |11111111|11111111|00100                  1fffe4  [21]\n" +
-     "       (217)  |11111111|11111111|00101                  1fffe5  [21]\n" +
-     "       (218)  |11111111|11111111|11111010|00           3ffffe8  [26]\n" +
-     "       (219)  |11111111|11111111|11111010|01           3ffffe9  [26]\n" +
-     "       (220)  |11111111|11111111|11111111|1101         ffffffd  [28]\n" +
-     "       (221)  |11111111|11111111|11111100|011          7ffffe3  [27]\n" +
-     "       (222)  |11111111|11111111|11111100|100          7ffffe4  [27]\n" +
-     "       (223)  |11111111|11111111|11111100|101          7ffffe5  [27]\n" +
-     "       (224)  |11111111|11111110|1100                    fffec  [20]\n" +
-     "       (225)  |11111111|11111111|11110011               fffff3  [24]\n" +
-     "       (226)  |11111111|11111110|1101                    fffed  [20]\n" +
-     "       (227)  |11111111|11111111|00110                  1fffe6  [21]\n" +
-     "       (228)  |11111111|11111111|101001                 3fffe9  [22]\n" +
-     "       (229)  |11111111|11111111|00111                  1fffe7  [21]\n" +
-     "       (230)  |11111111|11111111|01000                  1fffe8  [21]\n" +
-     "       (231)  |11111111|11111111|1110011                7ffff3  [23]\n" +
-     "       (232)  |11111111|11111111|101010                 3fffea  [22]\n" +
-     "       (233)  |11111111|11111111|101011                 3fffeb  [22]\n" +
-     "       (234)  |11111111|11111111|11110111|0            1ffffee  [25]\n" +
-     "       (235)  |11111111|11111111|11110111|1            1ffffef  [25]\n" +
-     "       (236)  |11111111|11111111|11110100               fffff4  [24]\n" +
-     "       (237)  |11111111|11111111|11110101               fffff5  [24]\n" +
-     "       (238)  |11111111|11111111|11111010|10           3ffffea  [26]\n" +
-     "       (239)  |11111111|11111111|1110100                7ffff4  [23]\n" +
-     "       (240)  |11111111|11111111|11111010|11           3ffffeb  [26]\n" +
-     "       (241)  |11111111|11111111|11111100|110          7ffffe6  [27]\n" +
-     "       (242)  |11111111|11111111|11111011|00           3ffffec  [26]\n" +
-     "       (243)  |11111111|11111111|11111011|01           3ffffed  [26]\n" +
-     "       (244)  |11111111|11111111|11111100|111          7ffffe7  [27]\n" +
-     "       (245)  |11111111|11111111|11111101|000          7ffffe8  [27]\n" +
-     "       (246)  |11111111|11111111|11111101|001          7ffffe9  [27]\n" +
-     "       (247)  |11111111|11111111|11111101|010          7ffffea  [27]\n" +
-     "       (248)  |11111111|11111111|11111101|011          7ffffeb  [27]\n" +
-     "       (249)  |11111111|11111111|11111111|1110         ffffffe  [28]\n" +
-     "       (250)  |11111111|11111111|11111101|100          7ffffec  [27]\n" +
-     "       (251)  |11111111|11111111|11111101|101          7ffffed  [27]\n" +
-     "       (252)  |11111111|11111111|11111101|110          7ffffee  [27]\n" +
-     "       (253)  |11111111|11111111|11111101|111          7ffffef  [27]\n" +
-     "       (254)  |11111111|11111111|11111110|000          7fffff0  [27]\n" +
-     "       (255)  |11111111|11111111|11111011|10           3ffffee  [26]\n" +
-     "   EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]";
-    // @formatter:on
-
-    @Test
-    public void read_table() {
-        Pattern line = Pattern.compile(
-                "\\(\\s*(?<ascii>\\d+)\\s*\\)\\s*(?<binary>(\\|(0|1)+)+)\\s*" +
-                        "(?<hex>[0-9a-zA-Z]+)\\s*\\[\\s*(?<len>\\d+)\\s*\\]");
-        Matcher m = line.matcher(SPEC);
-        int i = 0;
-        while (m.find()) {
-            String ascii = m.group("ascii");
-            String binary = m.group("binary").replaceAll("\\|", "");
-            String hex = m.group("hex");
-            String len = m.group("len");
-
-            // Several sanity checks for the data read from the table, just to
-            // make sure what we read makes sense
-            assertEquals(parseInt(len), binary.length());
-            assertEquals(parseInt(binary, 2), parseInt(hex, 16));
-
-            int expected = parseInt(ascii);
-
-            // TODO: find actual eos, do not hardcode it!
-            byte[] bytes = intToBytes(0x3fffffff, 30,
-                    parseInt(hex, 16), parseInt(len));
-
-            StringBuilder actual = new StringBuilder();
-            Huffman.Reader t = new Huffman.Reader();
-            t.read(ByteBuffer.wrap(bytes), actual, false, true);
-
-            // What has been read MUST represent a single symbol
-            assertEquals(actual.length(), 1, "ascii: " + ascii);
-
-            // It's a lot more visual to compare char as codes rather than
-            // characters (as some of them might not be visible)
-            assertEquals(actual.charAt(0), expected);
-            i++;
-        }
-        assertEquals(i, 257); // 256 + EOS
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.4.1
-    //
-    @Test
-    public void read_1() {
-        read("f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com");
-    }
-
-    @Test
-    public void write_1() {
-        write("www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.4.2
-    //
-    @Test
-    public void read_2() {
-        read("a8eb 1064 9cbf", "no-cache");
-    }
-
-    @Test
-    public void write_2() {
-        write("no-cache", "a8eb 1064 9cbf");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
-    //
-    @Test
-    public void read_3() {
-        read("25a8 49e9 5ba9 7d7f", "custom-key");
-    }
-
-    @Test
-    public void write_3() {
-        write("custom-key", "25a8 49e9 5ba9 7d7f");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
-    //
-    @Test
-    public void read_4() {
-        read("25a8 49e9 5bb8 e8b4 bf", "custom-value");
-    }
-
-    @Test
-    public void write_4() {
-        write("custom-value", "25a8 49e9 5bb8 e8b4 bf");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
-    //
-    @Test
-    public void read_5() {
-        read("6402", "302");
-    }
-
-    @Test
-    public void write_5() {
-        write("302", "6402");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
-    //
-    @Test
-    public void read_6() {
-        read("aec3 771a 4b", "private");
-    }
-
-    @Test
-    public void write_6() {
-        write("private", "aec3 771a 4b");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
-    //
-    @Test
-    public void read_7() {
-        read("d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff",
-                "Mon, 21 Oct 2013 20:13:21 GMT");
-    }
-
-    @Test
-    public void write_7() {
-        write("Mon, 21 Oct 2013 20:13:21 GMT",
-                "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
-    //
-    @Test
-    public void read_8() {
-        read("9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3",
-                "https://www.example.com");
-    }
-
-    @Test
-    public void write_8() {
-        write("https://www.example.com",
-                "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.2
-    //
-    @Test
-    public void read_9() {
-        read("640e ff", "307");
-    }
-
-    @Test
-    public void write_9() {
-        write("307", "640e ff");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
-    //
-    @Test
-    public void read_10() {
-        read("d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff",
-                "Mon, 21 Oct 2013 20:13:22 GMT");
-    }
-
-    @Test
-    public void write_10() {
-        write("Mon, 21 Oct 2013 20:13:22 GMT",
-                "d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
-    //
-    @Test
-    public void read_11() {
-        read("9bd9 ab", "gzip");
-    }
-
-    @Test
-    public void write_11() {
-        write("gzip", "9bd9 ab");
-    }
-
-    //
-    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
-    //
-    @Test
-    public void read_12() {
-        read("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 " +
-             "d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 " +
-             "3160 65c0 03ed 4ee5 b106 3d50 07",
-             "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
-    }
-
-    @Test
-    public void test_trie_has_no_empty_nodes() {
-        Huffman.Node root = Huffman.INSTANCE.getRoot();
-        Stack<Huffman.Node> backlog = new Stack<>();
-        backlog.push(root);
-        while (!backlog.isEmpty()) {
-            Huffman.Node n = backlog.pop();
-            // The only type of nodes we couldn't possibly catch during
-            // construction is an empty node: no children and no char
-            if (n.left != null) {
-                backlog.push(n.left);
-            }
-            if (n.right != null) {
-                backlog.push(n.right);
-            }
-            assertFalse(!n.charIsSet && n.left == null && n.right == null,
-                    "Empty node in the trie");
-        }
-    }
-
-    @Test
-    public void test_trie_has_257_nodes() {
-        int count = 0;
-        Huffman.Node root = Huffman.INSTANCE.getRoot();
-        Stack<Huffman.Node> backlog = new Stack<>();
-        backlog.push(root);
-        while (!backlog.isEmpty()) {
-            Huffman.Node n = backlog.pop();
-            if (n.left != null) {
-                backlog.push(n.left);
-            }
-            if (n.right != null) {
-                backlog.push(n.right);
-            }
-            if (n.isLeaf()) {
-                count++;
-            }
-        }
-        assertEquals(count, 257);
-    }
-
-    @Test
-    public void cant_encode_outside_byte() {
-        TestHelper.Block<Object> coding =
-                () -> new Huffman.Writer()
-                        .from(((char) 256) + "", 0, 1)
-                        .write(ByteBuffer.allocate(1));
-        RuntimeException e =
-                TestHelper.assertVoidThrows(RuntimeException.class, coding);
-        TestHelper.assertExceptionMessageContains(e, "char");
-    }
-
-    private static void read(String hexdump, String decoded) {
-        ByteBuffer source = SpecHelper.toBytes(hexdump);
-        Appendable actual = new StringBuilder();
-        new Huffman.Reader().read(source, actual, true);
-        assertEquals(actual.toString(), decoded);
-    }
-
-    private static void write(String decoded, String hexdump) {
-        int n = Huffman.INSTANCE.lengthOf(decoded);
-        ByteBuffer destination = ByteBuffer.allocate(n); // Extra margin (1) to test having more bytes in the destination than needed is ok
-        Huffman.Writer writer = new Huffman.Writer();
-        BuffersTestingKit.forEachSplit(destination, byteBuffers -> {
-            writer.from(decoded, 0, decoded.length());
-            boolean written = false;
-            for (ByteBuffer b : byteBuffers) {
-                int pos = b.position();
-                written = writer.write(b);
-                b.position(pos);
-            }
-            assertTrue(written);
-            ByteBuffer concated = BuffersTestingKit.concat(byteBuffers);
-            String actual = SpecHelper.toHexdump(concated);
-            assertEquals(actual, hexdump);
-            writer.reset();
-        });
-    }
-
-    //
-    // It's not very pretty, yes I know that
-    //
-    //      hex:
-    //
-    //      |31|30|...|N-1|...|01|00|
-    //                  \        /
-    //                  codeLength
-    //
-    //      hex <<= 32 - codeLength; (align to MSB):
-    //
-    //      |31|30|...|32-N|...|01|00|
-    //        \        /
-    //        codeLength
-    //
-    //      EOS:
-    //
-    //      |31|30|...|M-1|...|01|00|
-    //                   \        /
-    //                   eosLength
-    //
-    //      eos <<= 32 - eosLength; (align to MSB):
-    //
-    //      pad with MSBs of EOS:
-    //
-    //      |31|30|...|32-N|32-N-1|...|01|00|
-    //                     |    32|...|
-    //
-    //      Finally, split into byte[]
-    //
-    private byte[] intToBytes(int eos, int eosLength, int hex, int codeLength) {
-        hex <<= 32 - codeLength;
-        eos >>= codeLength - (32 - eosLength);
-        hex |= eos;
-        int n = (int) Math.ceil(codeLength / 8.0);
-        byte[] result = new byte[n];
-        for (int i = 0; i < n; i++) {
-            result[i] = (byte) (hex >> (32 - 8 * (i + 1)));
-        }
-        return result;
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/SpecHelper.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-//
-// THIS IS NOT A TEST
-//
-public final class SpecHelper {
-
-    private SpecHelper() {
-        throw new AssertionError();
-    }
-
-    public static ByteBuffer toBytes(String hexdump) {
-        Pattern hexByte = Pattern.compile("[0-9a-fA-F]{2}");
-        List<String> bytes = new ArrayList<>();
-        Matcher matcher = hexByte.matcher(hexdump);
-        while (matcher.find()) {
-            bytes.add(matcher.group(0));
-        }
-        ByteBuffer result = ByteBuffer.allocate(bytes.size());
-        for (String f : bytes) {
-            result.put((byte) Integer.parseInt(f, 16));
-        }
-        result.flip();
-        return result;
-    }
-
-    public static String toHexdump(ByteBuffer bb) {
-        List<String> words = new ArrayList<>();
-        int i = 0;
-        while (bb.hasRemaining()) {
-            if (i % 2 == 0) {
-                words.add("");
-            }
-            byte b = bb.get();
-            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
-            words.set(i / 2, words.get(i / 2) + hex);
-            i++;
-        }
-        return words.stream().collect(Collectors.joining(" "));
-    }
-}
--- a/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/TestHelper.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.httpclient.hpack;
-
-import org.testng.annotations.Test;
-
-import java.util.Objects;
-import java.util.Random;
-
-public final class TestHelper {
-
-    public static Random newRandom() {
-        long seed = Long.getLong("jdk.test.lib.random.seed", System.currentTimeMillis());
-        System.out.println("new java.util.Random(" + seed + ")");
-        return new Random(seed);
-    }
-
-    public static <T extends Throwable> T assertVoidThrows(Class<T> clazz, Block<?> code) {
-        return assertThrows(clazz, () -> {
-            code.run();
-            return null;
-        });
-    }
-
-    public static <T extends Throwable> T assertThrows(Class<T> clazz, ReturningBlock<?> code) {
-        Objects.requireNonNull(clazz, "clazz == null");
-        Objects.requireNonNull(code, "code == null");
-        try {
-            code.run();
-        } catch (Throwable t) {
-            if (clazz.isInstance(t)) {
-                return clazz.cast(t);
-            }
-            throw new AssertionError("Expected to catch exception of type "
-                    + clazz.getCanonicalName() + ", instead caught "
-                    + t.getClass().getCanonicalName(), t);
-
-        }
-        throw new AssertionError(
-                "Expected to catch exception of type " + clazz.getCanonicalName()
-                        + ", but caught nothing");
-    }
-
-    public static <T> T assertDoesNotThrow(ReturningBlock<T> code) {
-        Objects.requireNonNull(code, "code == null");
-        try {
-            return code.run();
-        } catch (Throwable t) {
-            throw new AssertionError(
-                    "Expected code block to exit normally, instead " +
-                            "caught " + t.getClass().getCanonicalName(), t);
-        }
-    }
-
-    public static void assertVoidDoesNotThrow(Block<?> code) {
-        Objects.requireNonNull(code, "code == null");
-        try {
-            code.run();
-        } catch (Throwable t) {
-            throw new AssertionError(
-                    "Expected code block to exit normally, instead " +
-                            "caught " + t.getClass().getCanonicalName(), t);
-        }
-    }
-
-
-    public static void assertExceptionMessageContains(Throwable t,
-                                                      CharSequence firstSubsequence,
-                                                      CharSequence... others) {
-        assertCharSequenceContains(t.getMessage(), firstSubsequence, others);
-    }
-
-    public static void assertCharSequenceContains(CharSequence s,
-                                                  CharSequence firstSubsequence,
-                                                  CharSequence... others) {
-        if (s == null) {
-            throw new NullPointerException("Exception message is null");
-        }
-        String str = s.toString();
-        String missing = null;
-        if (!str.contains(firstSubsequence.toString())) {
-            missing = firstSubsequence.toString();
-        } else {
-            for (CharSequence o : others) {
-                if (!str.contains(o.toString())) {
-                    missing = o.toString();
-                    break;
-                }
-            }
-        }
-        if (missing != null) {
-            throw new AssertionError("CharSequence '" + s + "'" + " does not "
-                    + "contain subsequence '" + missing + "'");
-        }
-    }
-
-    public interface ReturningBlock<T> {
-        T run() throws Throwable;
-    }
-
-    public interface Block<T> {
-        void run() throws Throwable;
-    }
-
-    // tests
-
-    @Test
-    public void assertThrows() {
-        assertThrows(NullPointerException.class, () -> ((Object) null).toString());
-    }
-
-    @Test
-    public void assertThrowsWrongType() {
-        try {
-            assertThrows(IllegalArgumentException.class, () -> ((Object) null).toString());
-        } catch (AssertionError e) {
-            Throwable cause = e.getCause();
-            String message = e.getMessage();
-            if (cause != null
-                    && cause instanceof NullPointerException
-                    && message != null
-                    && message.contains("instead caught")) {
-                return;
-            }
-        }
-        throw new AssertionError();
-    }
-
-    @Test
-    public void assertThrowsNoneCaught() {
-        try {
-            assertThrows(IllegalArgumentException.class, () -> null);
-        } catch (AssertionError e) {
-            Throwable cause = e.getCause();
-            String message = e.getMessage();
-            if (cause == null
-                    && message != null
-                    && message.contains("but caught nothing")) {
-                return;
-            }
-        }
-        throw new AssertionError();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/BinaryPrimitivesTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+import static jdk.incubator.http.internal.hpack.BuffersTestingKit.*;
+import static jdk.incubator.http.internal.hpack.TestHelper.newRandom;
+
+//
+// Some of the tests below overlap in what they test. This allows to diagnose
+// bugs quicker and with less pain by simply ruling out common working bits.
+//
+public final class BinaryPrimitivesTest {
+
+    private final Random rnd = newRandom();
+
+    @Test
+    public void integerRead1() {
+        verifyRead(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
+    }
+
+    @Test
+    public void integerRead2() {
+        verifyRead(bytes(0b00001010), 10, 5);
+    }
+
+    @Test
+    public void integerRead3() {
+        verifyRead(bytes(0b00101010), 42, 8);
+    }
+
+    @Test
+    public void integerWrite1() {
+        verifyWrite(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
+    }
+
+    @Test
+    public void integerWrite2() {
+        verifyWrite(bytes(0b00001010), 10, 5);
+    }
+
+    @Test
+    public void integerWrite3() {
+        verifyWrite(bytes(0b00101010), 42, 8);
+    }
+
+    //
+    // Since readInteger(x) is the inverse of writeInteger(x), thus:
+    //
+    // for all x: readInteger(writeInteger(x)) == x
+    //
+    @Test
+    public void integerIdentity() {
+        final int MAX_VALUE = 1 << 22;
+        int totalCases = 0;
+        int maxFilling = 0;
+        IntegerReader r = new IntegerReader();
+        IntegerWriter w = new IntegerWriter();
+        ByteBuffer buf = ByteBuffer.allocate(8);
+        for (int N = 1; N < 9; N++) {
+            for (int expected = 0; expected <= MAX_VALUE; expected++) {
+                w.reset().configure(expected, N, 1).write(buf);
+                buf.flip();
+                totalCases++;
+                maxFilling = Math.max(maxFilling, buf.remaining());
+                r.reset().configure(N).read(buf);
+                assertEquals(r.get(), expected);
+                buf.clear();
+            }
+        }
+        System.out.printf("totalCases: %,d, maxFilling: %,d, maxValue: %,d%n",
+                totalCases, maxFilling, MAX_VALUE);
+    }
+
+    @Test
+    public void integerReadChunked() {
+        final int NUM_TESTS = 1024;
+        IntegerReader r = new IntegerReader();
+        ByteBuffer bb = ByteBuffer.allocate(8);
+        IntegerWriter w = new IntegerWriter();
+        for (int i = 0; i < NUM_TESTS; i++) {
+            final int N = 1 + rnd.nextInt(8);
+            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
+            w.reset().configure(expected, N, rnd.nextInt()).write(bb);
+            bb.flip();
+
+            forEachSplit(bb,
+                    (buffers) -> {
+                        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
+                        r.configure(N);
+                        for (ByteBuffer b : buf) {
+                            r.read(b);
+                        }
+                        assertEquals(r.get(), expected);
+                        r.reset();
+                    });
+            bb.clear();
+        }
+    }
+
+    // FIXME: use maxValue in the test
+
+    @Test
+    // FIXME: tune values for better coverage
+    public void integerWriteChunked() {
+        ByteBuffer bb = ByteBuffer.allocate(6);
+        IntegerWriter w = new IntegerWriter();
+        IntegerReader r = new IntegerReader();
+        for (int i = 0; i < 1024; i++) { // number of tests
+            final int N = 1 + rnd.nextInt(8);
+            final int payload = rnd.nextInt(255);
+            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
+
+            forEachSplit(bb,
+                    (buffers) -> {
+                        List<ByteBuffer> buf = new ArrayList<>();
+                        relocateBuffers(injectEmptyBuffers(buffers)).forEach(buf::add);
+                        boolean written = false;
+                        w.configure(expected, N, payload); // TODO: test for payload it can be read after written
+                        for (ByteBuffer b : buf) {
+                            int pos = b.position();
+                            written = w.write(b);
+                            b.position(pos);
+                        }
+                        if (!written) {
+                            fail("please increase bb size");
+                        }
+                        r.configure(N).read(concat(buf));
+                        // TODO: check payload here
+                        assertEquals(r.get(), expected);
+                        w.reset();
+                        r.reset();
+                        bb.clear();
+                    });
+        }
+    }
+
+
+    //
+    // Since readString(x) is the inverse of writeString(x), thus:
+    //
+    // for all x: readString(writeString(x)) == x
+    //
+    @Test
+    public void stringIdentity() {
+        final int MAX_STRING_LENGTH = 4096;
+        ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6); // it takes 6 bytes to encode string length of Integer.MAX_VALUE
+        CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        StringReader reader = new StringReader();
+        StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+            for (int i = 0; i < 64; i++) {
+                // not so much "test in isolation", I know... we're testing .reset() as well
+                bytes.clear();
+                chars.clear();
+
+                byte[] b = new byte[len];
+                rnd.nextBytes(b);
+
+                String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+                boolean written = writer
+                        .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
+                        .write(bytes);
+
+                if (!written) {
+                    fail("please increase 'bytes' size");
+                }
+                bytes.flip();
+                reader.read(bytes, chars);
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                writer.reset();
+            }
+        }
+    }
+
+//    @Test
+//    public void huffmanStringWriteChunked() {
+//        fail();
+//    }
+//
+//    @Test
+//    public void huffmanStringReadChunked() {
+//        fail();
+//    }
+
+    @Test
+    public void stringWriteChunked() {
+        final int MAX_STRING_LENGTH = 8;
+        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
+        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        final StringReader reader = new StringReader();
+        final StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+
+            byte[] b = new byte[len];
+            rnd.nextBytes(b);
+
+            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+            forEachSplit(bytes, (buffers) -> {
+                writer.configure(expected, 0, expected.length(), false);
+                boolean written = false;
+                for (ByteBuffer buf : buffers) {
+                    int p0 = buf.position();
+                    written = writer.write(buf);
+                    buf.position(p0);
+                }
+                if (!written) {
+                    fail("please increase 'bytes' size");
+                }
+                reader.read(concat(buffers), chars);
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                writer.reset();
+                chars.clear();
+                bytes.clear();
+            });
+        }
+    }
+
+    @Test
+    public void stringReadChunked() {
+        final int MAX_STRING_LENGTH = 16;
+        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
+        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        final StringReader reader = new StringReader();
+        final StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+
+            byte[] b = new byte[len];
+            rnd.nextBytes(b);
+
+            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+            boolean written = writer
+                    .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
+                    .write(bytes);
+            writer.reset();
+
+            if (!written) {
+                fail("please increase 'bytes' size");
+            }
+            bytes.flip();
+
+            forEachSplit(bytes, (buffers) -> {
+                for (ByteBuffer buf : buffers) {
+                    int p0 = buf.position();
+                    reader.read(buf, chars);
+                    buf.position(p0);
+                }
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                chars.clear();
+            });
+
+            bytes.clear();
+        }
+    }
+
+//    @Test
+//    public void test_Huffman_String_Identity() {
+//        StringWriter writer = new StringWriter();
+//        StringReader reader = new StringReader();
+//        // 256 * 8 gives 2048 bits in case of plain 8 bit coding
+//        // 256 * 30 gives you 7680 bits or 960 bytes in case of almost
+//        //          improbable event of 256 30 bits symbols in a row
+//        ByteBuffer binary = ByteBuffer.allocate(960);
+//        CharBuffer text = CharBuffer.allocate(960 / 5); // 5 = minimum code length
+//        for (int len = 0; len < 128; len++) {
+//            for (int i = 0; i < 256; i++) {
+//                // not so much "test in isolation", I know...
+//                binary.clear();
+//
+//                byte[] bytes = new byte[len];
+//                rnd.nextBytes(bytes);
+//
+//                String s = new String(bytes, StandardCharsets.ISO_8859_1);
+//
+//                writer.write(CharBuffer.wrap(s), binary, true);
+//                binary.flip();
+//                reader.read(binary, text);
+//                text.flip();
+//                assertEquals(text.toString(), s);
+//            }
+//        }
+//    }
+
+    // TODO: atomic failures: e.g. readonly/overflow
+
+    private static byte[] bytes(int... data) {
+        byte[] bytes = new byte[data.length];
+        for (int i = 0; i < data.length; i++) {
+            bytes[i] = (byte) data[i];
+        }
+        return bytes;
+    }
+
+    private static void verifyRead(byte[] data, int expected, int N) {
+        ByteBuffer buf = ByteBuffer.wrap(data, 0, data.length);
+        IntegerReader reader = new IntegerReader();
+        reader.configure(N).read(buf);
+        assertEquals(expected, reader.get());
+    }
+
+    private void verifyWrite(byte[] expected, int data, int N) {
+        IntegerWriter w = new IntegerWriter();
+        ByteBuffer buf = ByteBuffer.allocate(2 * expected.length);
+        w.configure(data, N, 1).write(buf);
+        buf.flip();
+        assertEquals(ByteBuffer.wrap(expected), buf);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/BuffersTestingKit.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import static java.nio.ByteBuffer.allocate;
+
+public final class BuffersTestingKit {
+
+    /**
+     * Relocates a {@code [position, limit)} region of the given buffer to
+     * corresponding region in a new buffer starting with provided {@code
+     * newPosition}.
+     *
+     * <p> Might be useful to make sure ByteBuffer's users do not rely on any
+     * absolute positions, but solely on what's reported by position(), limit().
+     *
+     * <p> The contents between the given buffer and the returned one are not
+     * shared.
+     */
+    public static ByteBuffer relocate(ByteBuffer buffer, int newPosition,
+                                      int newCapacity) {
+        int oldPosition = buffer.position();
+        int oldLimit = buffer.limit();
+
+        if (newPosition + oldLimit - oldPosition > newCapacity) {
+            throw new IllegalArgumentException();
+        }
+
+        ByteBuffer result;
+        if (buffer.isDirect()) {
+            result = ByteBuffer.allocateDirect(newCapacity);
+        } else {
+            result = allocate(newCapacity);
+        }
+
+        result.position(newPosition);
+        result.put(buffer).limit(result.position()).position(newPosition);
+        buffer.position(oldPosition);
+
+        if (buffer.isReadOnly()) {
+            return result.asReadOnlyBuffer();
+        }
+        return result;
+    }
+
+    public static Iterable<? extends ByteBuffer> relocateBuffers(
+            Iterable<? extends ByteBuffer> source) {
+        return () ->
+                new Iterator<ByteBuffer>() {
+
+                    private final Iterator<? extends ByteBuffer> it = source.iterator();
+
+                    @Override
+                    public boolean hasNext() {
+                        return it.hasNext();
+                    }
+
+                    @Override
+                    public ByteBuffer next() {
+                        ByteBuffer buf = it.next();
+                        int remaining = buf.remaining();
+                        int newCapacity = remaining + random.nextInt(17);
+                        int newPosition = random.nextInt(newCapacity - remaining + 1);
+                        return relocate(buf, newPosition, newCapacity);
+                    }
+                };
+    }
+
+    // TODO: not always of size 0 (it's fine for buffer to report !b.hasRemaining())
+    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
+            Iterable<? extends ByteBuffer> source) {
+        return injectEmptyBuffers(source, () -> allocate(0));
+    }
+
+    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
+            Iterable<? extends ByteBuffer> source,
+            Supplier<? extends ByteBuffer> emptyBufferFactory) {
+
+        return () ->
+                new Iterator<ByteBuffer>() {
+
+                    private final Iterator<? extends ByteBuffer> it = source.iterator();
+                    private ByteBuffer next = calculateNext();
+
+                    private ByteBuffer calculateNext() {
+                        if (random.nextBoolean()) {
+                            return emptyBufferFactory.get();
+                        } else if (it.hasNext()) {
+                            return it.next();
+                        } else {
+                            return null;
+                        }
+                    }
+
+                    @Override
+                    public boolean hasNext() {
+                        return next != null;
+                    }
+
+                    @Override
+                    public ByteBuffer next() {
+                        if (!hasNext()) {
+                            throw new NoSuchElementException();
+                        }
+                        ByteBuffer next = this.next;
+                        this.next = calculateNext();
+                        return next;
+                    }
+                };
+    }
+
+    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split) {
+        return concat(split, ByteBuffer::allocate);
+    }
+
+    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split,
+                                    Function<? super Integer, ? extends ByteBuffer> concatBufferFactory) {
+        int size = 0;
+        for (ByteBuffer bb : split) {
+            size += bb.remaining();
+        }
+
+        ByteBuffer result = concatBufferFactory.apply(size);
+        for (ByteBuffer bb : split) {
+            result.put(bb);
+        }
+
+        result.flip();
+        return result;
+    }
+
+    public static void forEachSplit(ByteBuffer bb,
+                                    Consumer<? super Iterable<? extends ByteBuffer>> action) {
+        forEachSplit(bb.remaining(),
+                (lengths) -> {
+                    int end = bb.position();
+                    List<ByteBuffer> buffers = new LinkedList<>();
+                    for (int len : lengths) {
+                        ByteBuffer d = bb.duplicate();
+                        d.position(end);
+                        d.limit(end + len);
+                        end += len;
+                        buffers.add(d);
+                    }
+                    action.accept(buffers);
+                });
+    }
+
+    private static void forEachSplit(int n, Consumer<? super Iterable<? extends Integer>> action) {
+        forEachSplit(n, new Stack<>(), action);
+    }
+
+    private static void forEachSplit(int n, Stack<Integer> path,
+                                     Consumer<? super Iterable<? extends Integer>> action) {
+        if (n == 0) {
+            action.accept(path);
+        } else {
+            for (int i = 1; i <= n; i++) {
+                path.push(i);
+                forEachSplit(n - i, path, action);
+                path.pop();
+            }
+        }
+    }
+
+    private static final Random random = new Random();
+
+    private BuffersTestingKit() {
+        throw new InternalError();
+    }
+
+//    public static void main(String[] args) {
+//
+//        List<ByteBuffer> buffers = Arrays.asList(
+//                (ByteBuffer) allocate(3).position(1).limit(2),
+//                allocate(0),
+//                allocate(7));
+//
+//        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
+//        List<ByteBuffer> result = new ArrayList<>();
+//        buf.forEach(result::add);
+//        System.out.println(result);
+//    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/CircularBufferTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.hpack.HeaderTable.CircularBuffer;
+
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import static org.testng.Assert.assertEquals;
+import static jdk.incubator.http.internal.hpack.TestHelper.newRandom;
+
+public final class CircularBufferTest {
+
+    private final Random r = newRandom();
+
+    @BeforeClass
+    public void setUp() {
+        r.setSeed(System.currentTimeMillis());
+    }
+
+    @Test
+    public void queue() {
+        for (int capacity = 1; capacity <= 2048; capacity++) {
+            queueOnce(capacity, 32);
+        }
+    }
+
+    @Test
+    public void resize() {
+        for (int capacity = 1; capacity <= 4096; capacity++) {
+            resizeOnce(capacity);
+        }
+    }
+
+    @Test
+    public void downSizeEmptyBuffer() {
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(16);
+        buffer.resize(15);
+    }
+
+    private void resizeOnce(int capacity) {
+
+        int nextNumberToPut = 0;
+
+        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
+
+        // Fill full, so the next add will wrap
+        for (int i = 0; i < capacity; i++, nextNumberToPut++) {
+            buffer.add(nextNumberToPut);
+            referenceQueue.add(nextNumberToPut);
+        }
+        int gets = r.nextInt(capacity); // [0, capacity)
+        for (int i = 0; i < gets; i++) {
+            referenceQueue.poll();
+            buffer.remove();
+        }
+        int puts = r.nextInt(gets + 1); // [0, gets]
+        for (int i = 0; i < puts; i++, nextNumberToPut++) {
+            buffer.add(nextNumberToPut);
+            referenceQueue.add(nextNumberToPut);
+        }
+
+        Integer[] expected = referenceQueue.toArray(new Integer[0]);
+        buffer.resize(expected.length);
+
+        assertEquals(buffer.elements, expected);
+    }
+
+    private void queueOnce(int capacity, int numWraps) {
+
+        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
+
+        int nextNumberToPut = 0;
+        int totalPuts = 0;
+        int putsLimit = capacity * numWraps;
+        int remainingCapacity = capacity;
+        int size = 0;
+
+        while (totalPuts < putsLimit) {
+            assert remainingCapacity + size == capacity;
+            int puts = r.nextInt(remainingCapacity + 1); // [0, remainingCapacity]
+            remainingCapacity -= puts;
+            size += puts;
+            for (int i = 0; i < puts; i++, nextNumberToPut++) {
+                referenceQueue.add(nextNumberToPut);
+                buffer.add(nextNumberToPut);
+            }
+            totalPuts += puts;
+            int gets = r.nextInt(size + 1); // [0, size]
+            size -= gets;
+            remainingCapacity += gets;
+            for (int i = 0; i < gets; i++) {
+                Integer expected = referenceQueue.poll();
+                Integer actual = buffer.remove();
+                assertEquals(actual, expected);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/DecoderTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,689 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.Test;
+
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static jdk.incubator.http.internal.hpack.TestHelper.*;
+
+//
+// Tests whose names start with "testX" are the ones captured from real HPACK
+// use cases
+//
+public final class DecoderTest {
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
+    //
+    @Test
+    public void example1() {
+        // @formatter:off
+        test("400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
+             "746f 6d2d 6865 6164 6572",
+
+             "[  1] (s =  55) custom-key: custom-header\n" +
+             "      Table size:  55",
+
+             "custom-key: custom-header");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
+    //
+    @Test
+    public void example2() {
+        // @formatter:off
+        test("040c 2f73 616d 706c 652f 7061 7468",
+             "empty.",
+             ":path: /sample/path");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
+    //
+    @Test
+    public void example3() {
+        // @formatter:off
+        test("1008 7061 7373 776f 7264 0673 6563 7265\n" +
+             "74",
+             "empty.",
+             "password: secret");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
+    //
+    @Test
+    public void example4() {
+        // @formatter:off
+        test("82",
+             "empty.",
+             ":method: GET");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.3
+    //
+    @Test
+    public void example5() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+                "2e63 6f6d",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+
+        test(d, "8286 84be 5808 6e6f 2d63 6163 6865",
+
+                "[  1] (s =  53) cache-control: no-cache\n" +
+                "[  2] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 110",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com\n" +
+                "cache-control: no-cache");
+
+        test(d, "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
+                "0c63 7573 746f 6d2d 7661 6c75 65",
+
+                "[  1] (s =  54) custom-key: custom-value\n" +
+                "[  2] (s =  53) cache-control: no-cache\n" +
+                "[  3] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 164",
+
+                ":method: GET\n" +
+                ":scheme: https\n" +
+                ":path: /index.html\n" +
+                ":authority: www.example.com\n" +
+                "custom-key: custom-value");
+
+        // @formatter:on
+    }
+
+    @Test
+    public void example5AllSplits() {
+        // @formatter:off
+        testAllSplits(
+                "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+                "2e63 6f6d",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.4
+    //
+    @Test
+    public void example6() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
+                "ff",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+
+        test(d, "8286 84be 5886 a8eb 1064 9cbf",
+
+                "[  1] (s =  53) cache-control: no-cache\n" +
+                "[  2] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 110",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com\n" +
+                "cache-control: no-cache");
+
+        test(d, "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
+                "a849 e95b b8e8 b4bf",
+
+                "[  1] (s =  54) custom-key: custom-value\n" +
+                "[  2] (s =  53) cache-control: no-cache\n" +
+                "[  3] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 164",
+
+                ":method: GET\n" +
+                ":scheme: https\n" +
+                ":path: /index.html\n" +
+                ":authority: www.example.com\n" +
+                "custom-key: custom-value");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.5
+    //
+    @Test
+    public void example7() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "4803 3330 3258 0770 7269 7661 7465 611d\n" +
+                "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
+                "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
+                "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
+                "6c65 2e63 6f6d",
+
+                "[  1] (s =  63) location: https://www.example.com\n" +
+                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  3] (s =  52) cache-control: private\n" +
+                "[  4] (s =  42) :status: 302\n" +
+                "      Table size: 222",
+
+                ":status: 302\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "4803 3330 37c1 c0bf",
+
+                "[  1] (s =  42) :status: 307\n" +
+                "[  2] (s =  63) location: https://www.example.com\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  4] (s =  52) cache-control: private\n" +
+                "      Table size: 222",
+
+                ":status: 307\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
+                "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
+                "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
+                "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
+                "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
+                "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
+                "3d31",
+
+                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+                "[  2] (s =  52) content-encoding: gzip\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "      Table size: 215",
+
+                ":status: 200\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "location: https://www.example.com\n" +
+                "content-encoding: gzip\n" +
+                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.6
+    //
+    @Test
+    public void example8() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
+                "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
+                "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
+                "e9ae 82ae 43d3",
+
+                "[  1] (s =  63) location: https://www.example.com\n" +
+                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  3] (s =  52) cache-control: private\n" +
+                "[  4] (s =  42) :status: 302\n" +
+                "      Table size: 222",
+
+                ":status: 302\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "4883 640e ffc1 c0bf",
+
+                "[  1] (s =  42) :status: 307\n" +
+                "[  2] (s =  63) location: https://www.example.com\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  4] (s =  52) cache-control: private\n" +
+                "      Table size: 222",
+
+                ":status: 307\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
+                "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
+                "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
+                "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
+                "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+
+                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+                "[  2] (s =  52) content-encoding: gzip\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "      Table size: 215",
+
+                ":status: 200\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "location: https://www.example.com\n" +
+                "content-encoding: gzip\n" +
+                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+        // @formatter:on
+    }
+
+    @Test
+    // One of responses from Apache Server that helped to catch a bug
+    public void testX() {
+        Decoder d = new Decoder(4096);
+        // @formatter:off
+        test(d, "3fe1 1f88 6196 d07a be94 03ea 693f 7504\n" +
+                "00b6 a05c b827 2e32 fa98 b46f 769e 86b1\n" +
+                "9272 b025 da5c 2ea9 fd70 a8de 7fb5 3556\n" +
+                "5ab7 6ece c057 02e2 2ad2 17bf 6c96 d07a\n" +
+                "be94 0854 cb6d 4a08 0075 40bd 71b6 6e05\n" +
+                "a531 68df 0f13 8efe 4522 cd32 21b6 5686\n" +
+                "eb23 781f cf52 848f d24a 8f0f 0d02 3435\n" +
+                "5f87 497c a589 d34d 1f",
+
+                "[  1] (s =  53) content-type: text/html\n" +
+                "[  2] (s =  50) accept-ranges: bytes\n" +
+                "[  3] (s =  74) last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
+                "[  4] (s =  77) server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
+                "[  5] (s =  65) date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
+                "      Table size: 319",
+
+                ":status: 200\n" +
+                "date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
+                "server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
+                "last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
+                "etag: \"2d-432a5e4a73a80\"\n" +
+                "accept-ranges: bytes\n" +
+                "content-length: 45\n" +
+                "content-type: text/html");
+        // @formatter:on
+    }
+
+    @Test
+    public void testX1() {
+        // Supplier of a decoder with a particular state
+        Supplier<Decoder> s = () -> {
+            Decoder d = new Decoder(4096);
+            // @formatter:off
+            test(d, "88 76 92 ca 54 a7 d7 f4 fa ec af ed 6d da 61 d7 bb 1e ad ff" +
+                    "df 61 97 c3 61 be 94 13 4a 65 b6 a5 04 00 b8 a0 5a b8 db 77" +
+                    "1b 71 4c 5a 37 ff 0f 0d 84 08 00 00 03",
+
+                    "[  1] (s =  65) date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
+                    "[  2] (s =  59) server: Jetty(9.3.z-SNAPSHOT)\n" +
+                    "      Table size: 124",
+
+                    ":status: 200\n" +
+                    "server: Jetty(9.3.z-SNAPSHOT)\n" +
+                    "date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
+                    "content-length: 100000"
+            );
+            // @formatter:on
+            return d;
+        };
+        // For all splits of the following data fed to the supplied decoder we
+        // must get what's expected
+        // @formatter:off
+        testAllSplits(s,
+                "88 bf be 0f 0d 84 08 00 00 03",
+
+                "[  1] (s =  65) date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
+                "[  2] (s =  59) server: Jetty(9.3.z-SNAPSHOT)\n" +
+                "      Table size: 124",
+
+                ":status: 200\n" +
+                "server: Jetty(9.3.z-SNAPSHOT)\n" +
+                "date: Fri, 24 Jun 2016 14:55:56 GMT\n" +
+                "content-length: 100000");
+        // @formatter:on
+    }
+
+    //
+    // This test is missing in the spec
+    //
+    @Test
+    public void sizeUpdate() {
+        Decoder d = new Decoder(4096);
+        assertEquals(d.getTable().maxSize(), 4096);
+        d.decode(ByteBuffer.wrap(new byte[]{0b00111110}), true, nopCallback()); // newSize = 30
+        assertEquals(d.getTable().maxSize(), 30);
+    }
+
+    @Test
+    public void incorrectSizeUpdate() {
+        ByteBuffer b = ByteBuffer.allocate(8);
+        Encoder e = new Encoder(8192) {
+            @Override
+            protected int calculateCapacity(int maxCapacity) {
+                return maxCapacity;
+            }
+        };
+        e.header("a", "b");
+        e.encode(b);
+        b.flip();
+        {
+            Decoder d = new Decoder(4096);
+            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
+                    () -> d.decode(b, true, (name, value) -> { }));
+
+            assertNotNull(ex.getCause());
+            assertEquals(ex.getCause().getClass(), ProtocolException.class);
+        }
+        b.flip();
+        {
+            Decoder d = new Decoder(4096);
+            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
+                    () -> d.decode(b, false, (name, value) -> { }));
+
+            assertNotNull(ex.getCause());
+            assertEquals(ex.getCause().getClass(), ProtocolException.class);
+        }
+    }
+
+    @Test
+    public void corruptedHeaderBlockInteger() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed
+                (byte) 0b10011010  // 25 + ...
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    // 5.1.  Integer Representation
+    // ...
+    // Integer encodings that exceed implementation limits -- in value or octet
+    // length -- MUST be treated as decoding errors. Different limits can
+    // be set for each of the different uses of integers, based on
+    // implementation constraints.
+    @Test
+    public void headerBlockIntegerNoOverflow() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed + 127
+                // Integer.MAX_VALUE - 127 (base 128, little-endian):
+                (byte) 0b10000000,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b00000111
+        });
+
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "index=2147483647");
+    }
+
+    @Test
+    public void headerBlockIntegerOverflow() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed + 127
+                // Integer.MAX_VALUE - 127 + 1 (base 128, little endian):
+                (byte) 0b10000001,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b00000111
+        });
+
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Integer overflow");
+    }
+
+    @Test
+    public void corruptedHeaderBlockString1() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                0b00001000, // huffman=false, length=8
+                0b00000000, // \
+                0b00000000, //  but only 3 octets available...
+                0b00000000  // /
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    @Test
+    public void corruptedHeaderBlockString2() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10001000, // huffman=true, length=8
+                0b00000000, // \
+                0b00000000, //  \
+                0b00000000, //   but only 5 octets available...
+                0b00000000, //  /
+                0b00000000  // /
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A Huffman-encoded string literal containing the EOS symbol MUST be
+    // treated as a decoding error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringEOS() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000110, // huffman=true, length=6
+                0b00011001, 0b01001101, (byte) 0b11111111,
+                (byte) 0b11111111, (byte) 0b11111111, (byte) 0b11111100
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Encountered EOS");
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A padding strictly longer than 7 bits MUST be treated as a decoding
+    // error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringLongPadding1() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01001101, (byte) 0b11111111
+                // len("aei") + len(padding) = (5 + 5 + 5) + (9)
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Padding is too long", "len=9");
+    }
+
+    @Test
+    public void corruptedHeaderBlockHuffmanStringLongPadding2() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01111010, (byte) 0b11111111
+                // len("aek") + len(padding) = (5 + 5 + 7) + (7)
+        });
+        assertVoidDoesNotThrow(() -> d.decode(data, true, nopCallback()));
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A padding not corresponding to the most significant bits of the code
+    // for the EOS symbol MUST be treated as a decoding error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringNotEOSPadding() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01111010, (byte) 0b11111110
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Not a EOS prefix");
+    }
+
+    @Test
+    public void argsTestBiConsumerIsNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(ByteBuffer.allocate(16), true, null));
+    }
+
+    @Test
+    public void argsTestByteBufferIsNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(null, true, nopCallback()));
+    }
+
+    @Test
+    public void argsTestBothAreNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(null, true, null));
+    }
+
+    private static void test(String hexdump,
+                             String headerTable, String headerList) {
+        test(new Decoder(4096), hexdump, headerTable, headerList);
+    }
+
+    private static void testAllSplits(String hexdump,
+                                      String expectedHeaderTable,
+                                      String expectedHeaderList) {
+        testAllSplits(() -> new Decoder(256), hexdump, expectedHeaderTable, expectedHeaderList);
+    }
+
+    private static void testAllSplits(Supplier<Decoder> supplier, String hexdump,
+                                      String expectedHeaderTable, String expectedHeaderList) {
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+
+        BuffersTestingKit.forEachSplit(source, iterable -> {
+            List<String> actual = new LinkedList<>();
+            Iterator<? extends ByteBuffer> i = iterable.iterator();
+            if (!i.hasNext()) {
+                return;
+            }
+            Decoder d = supplier.get();
+            do {
+                ByteBuffer n = i.next();
+                d.decode(n, !i.hasNext(), (name, value) -> {
+                    if (value == null) {
+                        actual.add(name.toString());
+                    } else {
+                        actual.add(name + ": " + value);
+                    }
+                });
+            } while (i.hasNext());
+            assertEquals(d.getTable().getStateString(), expectedHeaderTable);
+            assertEquals(actual.stream().collect(Collectors.joining("\n")), expectedHeaderList);
+        });
+    }
+
+    //
+    // Sometimes we need to keep the same decoder along several runs,
+    // as it models the same connection
+    //
+    private static void test(Decoder d, String hexdump,
+                             String expectedHeaderTable, String expectedHeaderList) {
+
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+
+        List<String> actual = new LinkedList<>();
+        d.decode(source, true, (name, value) -> {
+            if (value == null) {
+                actual.add(name.toString());
+            } else {
+                actual.add(name + ": " + value);
+            }
+        });
+
+        assertEquals(d.getTable().getStateString(), expectedHeaderTable);
+        assertEquals(actual.stream().collect(Collectors.joining("\n")), expectedHeaderList);
+    }
+
+    private static DecodingCallback nopCallback() {
+        return (t, u) -> { };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/EncoderTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,692 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import static jdk.incubator.http.internal.hpack.BuffersTestingKit.concat;
+import static jdk.incubator.http.internal.hpack.BuffersTestingKit.forEachSplit;
+import static jdk.incubator.http.internal.hpack.SpecHelper.toHexdump;
+import static jdk.incubator.http.internal.hpack.TestHelper.assertVoidThrows;
+import static java.util.Arrays.asList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+// TODO: map textual representation of commands from the spec to actual
+// calls to encoder (actually, this is a good idea for decoder as well)
+public final class EncoderTest {
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
+    //
+    @Test
+    public void example1() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literalWithIndexing("custom-key", false, "custom-header", false);
+        // @formatter:off
+        test(e,
+
+             "400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
+             "746f 6d2d 6865 6164 6572",
+
+             "[  1] (s =  55) custom-key: custom-header\n" +
+             "      Table size:  55");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
+    //
+    @Test
+    public void example2() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literal(4, "/sample/path", false);
+        // @formatter:off
+        test(e,
+
+             "040c 2f73 616d 706c 652f 7061 7468",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
+    //
+    @Test
+    public void example3() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literalNeverIndexed("password", false, "secret", false);
+        // @formatter:off
+        test(e,
+
+             "1008 7061 7373 776f 7264 0673 6563 7265\n" +
+             "74",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
+    //
+    @Test
+    public void example4() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.indexed(2);
+        // @formatter:off
+        test(e,
+
+             "82",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.3
+    //
+    @Test
+    public void example5() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(64);
+        e.indexed(2);
+        e.encode(output);
+        e.indexed(6);
+        e.encode(output);
+        e.indexed(4);
+        e.encode(output);
+        e.literalWithIndexing(1, "www.example.com", false);
+        e.encode(output);
+
+        output.flip();
+
+        // @formatter:off
+        test(e, output,
+
+             "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+             "2e63 6f6d",
+
+             "[  1] (s =  57) :authority: www.example.com\n" +
+             "      Table size:  57");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 6);
+        e.encode(output);
+        e.indexed( 4);
+        e.encode(output);
+        e.indexed(62);
+        e.encode(output);
+        e.literalWithIndexing(24, "no-cache", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8286 84be 5808 6e6f 2d63 6163 6865",
+
+             "[  1] (s =  53) cache-control: no-cache\n" +
+             "[  2] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 110");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 7);
+        e.encode(output);
+        e.indexed( 5);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+        e.literalWithIndexing("custom-key", false, "custom-value", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
+             "0c63 7573 746f 6d2d 7661 6c75 65",
+
+             "[  1] (s =  54) custom-key: custom-value\n" +
+             "[  2] (s =  53) cache-control: no-cache\n" +
+             "[  3] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 164");
+        // @formatter:on
+    }
+
+    @Test
+    public void example5AllSplits() {
+
+        List<Consumer<Encoder>> actions = new LinkedList<>();
+        actions.add(e -> e.indexed(2));
+        actions.add(e -> e.indexed(6));
+        actions.add(e -> e.indexed(4));
+        actions.add(e -> e.literalWithIndexing(1, "www.example.com", false));
+
+        encodeAllSplits(
+                actions,
+
+                "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+                "2e63 6f6d",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57");
+    }
+
+    private static void encodeAllSplits(Iterable<Consumer<Encoder>> consumers,
+                                        String expectedHexdump,
+                                        String expectedTableState) {
+        ByteBuffer buffer = SpecHelper.toBytes(expectedHexdump);
+        erase(buffer); // Zeroed buffer of size needed to hold the encoding
+        forEachSplit(buffer, iterable -> {
+            List<ByteBuffer> copy = new LinkedList<>();
+            iterable.forEach(b -> copy.add(ByteBuffer.allocate(b.remaining())));
+            Iterator<ByteBuffer> output = copy.iterator();
+            if (!output.hasNext()) {
+                throw new IllegalStateException("No buffers to encode to");
+            }
+            Encoder e = newCustomEncoder(256); // FIXME: pull up (as a parameter)
+            drainInitialUpdate(e);
+            boolean encoded;
+            ByteBuffer b = output.next();
+            for (Consumer<Encoder> c : consumers) {
+                c.accept(e);
+                do {
+                    encoded = e.encode(b);
+                    if (!encoded) {
+                        if (output.hasNext()) {
+                            b = output.next();
+                        } else {
+                            throw new IllegalStateException("No room for encoding");
+                        }
+                    }
+                }
+                while (!encoded);
+            }
+            copy.forEach(Buffer::flip);
+            ByteBuffer data = concat(copy);
+            test(e, data, expectedHexdump, expectedTableState);
+        });
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.4
+    //
+    @Test
+    public void example6() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(64);
+        e.indexed(2);
+        e.encode(output);
+        e.indexed(6);
+        e.encode(output);
+        e.indexed(4);
+        e.encode(output);
+        e.literalWithIndexing(1, "www.example.com", true);
+        e.encode(output);
+
+        output.flip();
+
+        // @formatter:off
+        test(e, output,
+
+             "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
+             "ff",
+
+             "[  1] (s =  57) :authority: www.example.com\n" +
+             "      Table size:  57");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 6);
+        e.encode(output);
+        e.indexed( 4);
+        e.encode(output);
+        e.indexed(62);
+        e.encode(output);
+        e.literalWithIndexing(24, "no-cache", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8286 84be 5886 a8eb 1064 9cbf",
+
+             "[  1] (s =  53) cache-control: no-cache\n" +
+             "[  2] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 110");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 7);
+        e.encode(output);
+        e.indexed( 5);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+        e.literalWithIndexing("custom-key", true, "custom-value", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
+             "a849 e95b b8e8 b4bf",
+
+             "[  1] (s =  54) custom-key: custom-value\n" +
+             "[  2] (s =  53) cache-control: no-cache\n" +
+             "[  3] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 164");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.5
+    //
+    @Test
+    public void example7() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(128);
+        // @formatter:off
+        e.literalWithIndexing( 8, "302", false);
+        e.encode(output);
+        e.literalWithIndexing(24, "private", false);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", false);
+        e.encode(output);
+        e.literalWithIndexing(46, "https://www.example.com", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4803 3330 3258 0770 7269 7661 7465 611d\n" +
+             "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
+             "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
+             "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
+             "6c65 2e63 6f6d",
+
+             "[  1] (s =  63) location: https://www.example.com\n" +
+             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  3] (s =  52) cache-control: private\n" +
+             "[  4] (s =  42) :status: 302\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.literalWithIndexing( 8, "307", false);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4803 3330 37c1 c0bf",
+
+             "[  1] (s =  42) :status: 307\n" +
+             "[  2] (s =  63) location: https://www.example.com\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  4] (s =  52) cache-control: private\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.indexed( 8);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", false);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.literalWithIndexing(26, "gzip", false);
+        e.encode(output);
+        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
+             "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
+             "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
+             "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
+             "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
+             "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
+             "3d31",
+
+             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+             "[  2] (s =  52) content-encoding: gzip\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+             "      Table size: 215");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.6
+    //
+    @Test
+    public void example8() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(128);
+        // @formatter:off
+        e.literalWithIndexing( 8, "302", true);
+        e.encode(output);
+        e.literalWithIndexing(24, "private", true);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", true);
+        e.encode(output);
+        e.literalWithIndexing(46, "https://www.example.com", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
+             "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
+             "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
+             "e9ae 82ae 43d3",
+
+             "[  1] (s =  63) location: https://www.example.com\n" +
+             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  3] (s =  52) cache-control: private\n" +
+             "[  4] (s =  42) :status: 302\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.literalWithIndexing( 8, "307", true);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4883 640e ffc1 c0bf",
+
+             "[  1] (s =  42) :status: 307\n" +
+             "[  2] (s =  63) location: https://www.example.com\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  4] (s =  52) cache-control: private\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.indexed( 8);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", true);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.literalWithIndexing(26, "gzip", true);
+        e.encode(output);
+        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
+             "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
+             "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
+             "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
+             "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+
+             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+             "[  2] (s =  52) content-encoding: gzip\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+             "      Table size: 215");
+        // @formatter:on
+    }
+
+    @Test
+    public void initialSizeUpdateDefaultEncoder() {
+        Function<Integer, Encoder> e = Encoder::new;
+        testSizeUpdate(e, 1024, asList(), asList(0));
+        testSizeUpdate(e, 1024, asList(1024), asList(0));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList(0));
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(0));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(0));
+        testSizeUpdate(e, 1024, asList(512, 2048), asList(0));
+    }
+
+    @Test
+    public void initialSizeUpdateCustomEncoder() {
+        Function<Integer, Encoder> e = EncoderTest::newCustomEncoder;
+        testSizeUpdate(e, 1024, asList(), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(512, 2048), asList(2048));
+    }
+
+    @Test
+    public void seriesOfSizeUpdatesDefaultEncoder() {
+        Function<Integer, Encoder> e = c -> {
+            Encoder encoder = new Encoder(c);
+            drainInitialUpdate(encoder);
+            return encoder;
+        };
+        testSizeUpdate(e, 0, asList(0), asList());
+        testSizeUpdate(e, 1024, asList(1024), asList());
+        testSizeUpdate(e, 1024, asList(2048), asList());
+        testSizeUpdate(e, 1024, asList(512), asList());
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 2048), asList());
+        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 512), asList());
+        testSizeUpdate(e, 1024, asList(512, 1024), asList());
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#section-4.2
+    //
+    @Test
+    public void seriesOfSizeUpdatesCustomEncoder() {
+        Function<Integer, Encoder> e = c -> {
+            Encoder encoder = newCustomEncoder(c);
+            drainInitialUpdate(encoder);
+            return encoder;
+        };
+        testSizeUpdate(e, 0, asList(0), asList());
+        testSizeUpdate(e, 1024, asList(1024), asList());
+        testSizeUpdate(e, 1024, asList(2048), asList(2048));
+        testSizeUpdate(e, 1024, asList(512), asList(512));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 2048), asList(2048));
+        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(512, 1024));
+    }
+
+    @Test
+    public void callSequenceViolations() {
+        {   // Hasn't set up a header
+            Encoder e = new Encoder(0);
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+        {   // Can't set up header while there's an unfinished encoding
+            Encoder e = new Encoder(0);
+            e.indexed(32);
+            assertVoidThrows(IllegalStateException.class, () -> e.indexed(32));
+        }
+        {   // Can't setMaxCapacity while there's an unfinished encoding
+            Encoder e = new Encoder(0);
+            e.indexed(32);
+            assertVoidThrows(IllegalStateException.class, () -> e.setMaxCapacity(512));
+        }
+        {   // Hasn't set up a header
+            Encoder e = new Encoder(0);
+            e.setMaxCapacity(256);
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+        {   // Hasn't set up a header after the previous encoding
+            Encoder e = new Encoder(0);
+            e.indexed(0);
+            boolean encoded = e.encode(ByteBuffer.allocate(16));
+            assertTrue(encoded); // assumption
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+    }
+
+    private static void test(Encoder encoder,
+                             String expectedTableState,
+                             String expectedHexdump) {
+
+        ByteBuffer b = ByteBuffer.allocate(128);
+        encoder.encode(b);
+        b.flip();
+        test(encoder, b, expectedTableState, expectedHexdump);
+    }
+
+    private static void test(Encoder encoder,
+                             ByteBuffer output,
+                             String expectedHexdump,
+                             String expectedTableState) {
+
+        String actualTableState = encoder.getHeaderTable().getStateString();
+        assertEquals(actualTableState, expectedTableState);
+
+        String actualHexdump = toHexdump(output);
+        assertEquals(actualHexdump, expectedHexdump.replaceAll("\\n", " "));
+    }
+
+    // initial size - the size encoder is constructed with
+    // updates      - a sequence of values for consecutive calls to encoder.setMaxCapacity
+    // expected     - a sequence of values expected to be decoded by a decoder
+    private void testSizeUpdate(Function<Integer, Encoder> encoder,
+                                int initialSize,
+                                List<Integer> updates,
+                                List<Integer> expected) {
+        Encoder e = encoder.apply(initialSize);
+        updates.forEach(e::setMaxCapacity);
+        ByteBuffer b = ByteBuffer.allocate(64);
+        e.header("a", "b");
+        e.encode(b);
+        b.flip();
+        Decoder d = new Decoder(updates.isEmpty() ? initialSize : Collections.max(updates));
+        List<Integer> actual = new ArrayList<>();
+        d.decode(b, true, new DecodingCallback() {
+            @Override
+            public void onDecoded(CharSequence name, CharSequence value) { }
+
+            @Override
+            public void onSizeUpdate(int capacity) {
+                actual.add(capacity);
+            }
+        });
+        assertEquals(actual, expected);
+    }
+
+    //
+    // Default encoder does not need any table, therefore a subclass that
+    // behaves differently is needed
+    //
+    private static Encoder newCustomEncoder(int maxCapacity) {
+        return new Encoder(maxCapacity) {
+            @Override
+            protected int calculateCapacity(int maxCapacity) {
+                return maxCapacity;
+            }
+        };
+    }
+
+    private static void drainInitialUpdate(Encoder e) {
+        ByteBuffer b = ByteBuffer.allocate(4);
+        e.header("a", "b");
+        boolean done;
+        do {
+            done = e.encode(b);
+            b.flip();
+        } while (!done);
+    }
+
+    private static void erase(ByteBuffer buffer) {
+        buffer.clear();
+        while (buffer.hasRemaining()) {
+            buffer.put((byte) 0);
+        }
+        buffer.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/HeaderTableTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.hpack.HeaderTable.HeaderField;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.String.format;
+import static org.testng.Assert.assertEquals;
+import static jdk.incubator.http.internal.hpack.TestHelper.assertExceptionMessageContains;
+import static jdk.incubator.http.internal.hpack.TestHelper.assertThrows;
+import static jdk.incubator.http.internal.hpack.TestHelper.assertVoidThrows;
+import static jdk.incubator.http.internal.hpack.TestHelper.newRandom;
+
+public class HeaderTableTest {
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-A
+    //
+    // @formatter:off
+    private static final String SPEC =
+       "          | 1     | :authority                  |               |\n" +
+       "          | 2     | :method                     | GET           |\n" +
+       "          | 3     | :method                     | POST          |\n" +
+       "          | 4     | :path                       | /             |\n" +
+       "          | 5     | :path                       | /index.html   |\n" +
+       "          | 6     | :scheme                     | http          |\n" +
+       "          | 7     | :scheme                     | https         |\n" +
+       "          | 8     | :status                     | 200           |\n" +
+       "          | 9     | :status                     | 204           |\n" +
+       "          | 10    | :status                     | 206           |\n" +
+       "          | 11    | :status                     | 304           |\n" +
+       "          | 12    | :status                     | 400           |\n" +
+       "          | 13    | :status                     | 404           |\n" +
+       "          | 14    | :status                     | 500           |\n" +
+       "          | 15    | accept-charset              |               |\n" +
+       "          | 16    | accept-encoding             | gzip, deflate |\n" +
+       "          | 17    | accept-language             |               |\n" +
+       "          | 18    | accept-ranges               |               |\n" +
+       "          | 19    | accept                      |               |\n" +
+       "          | 20    | access-control-allow-origin |               |\n" +
+       "          | 21    | age                         |               |\n" +
+       "          | 22    | allow                       |               |\n" +
+       "          | 23    | authorization               |               |\n" +
+       "          | 24    | cache-control               |               |\n" +
+       "          | 25    | content-disposition         |               |\n" +
+       "          | 26    | content-encoding            |               |\n" +
+       "          | 27    | content-language            |               |\n" +
+       "          | 28    | content-length              |               |\n" +
+       "          | 29    | content-location            |               |\n" +
+       "          | 30    | content-range               |               |\n" +
+       "          | 31    | content-type                |               |\n" +
+       "          | 32    | cookie                      |               |\n" +
+       "          | 33    | date                        |               |\n" +
+       "          | 34    | etag                        |               |\n" +
+       "          | 35    | expect                      |               |\n" +
+       "          | 36    | expires                     |               |\n" +
+       "          | 37    | from                        |               |\n" +
+       "          | 38    | host                        |               |\n" +
+       "          | 39    | if-match                    |               |\n" +
+       "          | 40    | if-modified-since           |               |\n" +
+       "          | 41    | if-none-match               |               |\n" +
+       "          | 42    | if-range                    |               |\n" +
+       "          | 43    | if-unmodified-since         |               |\n" +
+       "          | 44    | last-modified               |               |\n" +
+       "          | 45    | link                        |               |\n" +
+       "          | 46    | location                    |               |\n" +
+       "          | 47    | max-forwards                |               |\n" +
+       "          | 48    | proxy-authenticate          |               |\n" +
+       "          | 49    | proxy-authorization         |               |\n" +
+       "          | 50    | range                       |               |\n" +
+       "          | 51    | referer                     |               |\n" +
+       "          | 52    | refresh                     |               |\n" +
+       "          | 53    | retry-after                 |               |\n" +
+       "          | 54    | server                      |               |\n" +
+       "          | 55    | set-cookie                  |               |\n" +
+       "          | 56    | strict-transport-security   |               |\n" +
+       "          | 57    | transfer-encoding           |               |\n" +
+       "          | 58    | user-agent                  |               |\n" +
+       "          | 59    | vary                        |               |\n" +
+       "          | 60    | via                         |               |\n" +
+       "          | 61    | www-authenticate            |               |\n";
+    // @formatter:on
+
+    private static final int STATIC_TABLE_LENGTH = createStaticEntries().size();
+    private final Random rnd = newRandom();
+
+    @Test
+    public void staticData() {
+        HeaderTable table = new HeaderTable(0);
+        Map<Integer, HeaderField> staticHeaderFields = createStaticEntries();
+
+        Map<String, Integer> minimalIndexes = new HashMap<>();
+
+        for (Map.Entry<Integer, HeaderField> e : staticHeaderFields.entrySet()) {
+            Integer idx = e.getKey();
+            String hName = e.getValue().name;
+            Integer midx = minimalIndexes.get(hName);
+            if (midx == null) {
+                minimalIndexes.put(hName, idx);
+            } else {
+                minimalIndexes.put(hName, Math.min(idx, midx));
+            }
+        }
+
+        staticHeaderFields.entrySet().forEach(
+                e -> {
+                    // lookup
+                    HeaderField actualHeaderField = table.get(e.getKey());
+                    HeaderField expectedHeaderField = e.getValue();
+                    assertEquals(actualHeaderField, expectedHeaderField);
+
+                    // reverse lookup (name, value)
+                    String hName = expectedHeaderField.name;
+                    String hValue = expectedHeaderField.value;
+                    int expectedIndex = e.getKey();
+                    int actualIndex = table.indexOf(hName, hValue);
+
+                    assertEquals(actualIndex, expectedIndex);
+
+                    // reverse lookup (name)
+                    int expectedMinimalIndex = minimalIndexes.get(hName);
+                    int actualMinimalIndex = table.indexOf(hName, "blah-blah");
+
+                    assertEquals(-actualMinimalIndex, expectedMinimalIndex);
+                }
+        );
+    }
+
+    @Test
+    public void constructorSetsMaxSize() {
+        int size = rnd.nextInt(64);
+        HeaderTable t = new HeaderTable(size);
+        assertEquals(t.size(), 0);
+        assertEquals(t.maxSize(), size);
+    }
+
+    @Test
+    public void negativeMaximumSize() {
+        int maxSize = -(rnd.nextInt(100) + 1); // [-100, -1]
+        IllegalArgumentException e =
+                assertVoidThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).setMaxSize(maxSize));
+        assertExceptionMessageContains(e, "maxSize");
+    }
+
+    @Test
+    public void zeroMaximumSize() {
+        HeaderTable table = new HeaderTable(0);
+        table.setMaxSize(0);
+        assertEquals(table.maxSize(), 0);
+    }
+
+    @Test
+    public void negativeIndex() {
+        int idx = -(rnd.nextInt(256) + 1); // [-256, -1]
+        IllegalArgumentException e =
+                assertVoidThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).get(idx));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void zeroIndex() {
+        IllegalArgumentException e =
+                assertThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).get(0));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void length() {
+        HeaderTable table = new HeaderTable(0);
+        assertEquals(table.length(), STATIC_TABLE_LENGTH);
+    }
+
+    @Test
+    public void indexOutsideStaticRange() {
+        HeaderTable table = new HeaderTable(0);
+        int idx = table.length() + (rnd.nextInt(256) + 1);
+        IllegalArgumentException e =
+                assertThrows(IllegalArgumentException.class,
+                        () -> table.get(idx));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void entryPutAfterStaticArea() {
+        HeaderTable table = new HeaderTable(256);
+        int idx = table.length() + 1;
+        assertThrows(IllegalArgumentException.class, () -> table.get(idx));
+
+        byte[] bytes = new byte[32];
+        rnd.nextBytes(bytes);
+        String name = new String(bytes, StandardCharsets.ISO_8859_1);
+        String value = "custom-value";
+
+        table.put(name, value);
+        HeaderField f = table.get(idx);
+        assertEquals(name, f.name);
+        assertEquals(value, f.value);
+    }
+
+    @Test
+    public void staticTableHasZeroSize() {
+        HeaderTable table = new HeaderTable(0);
+        assertEquals(0, table.size());
+    }
+
+    @Test
+    public void lowerIndexPriority() {
+        HeaderTable table = new HeaderTable(256);
+        int oldLength = table.length();
+        table.put("bender", "rodriguez");
+        table.put("bender", "rodriguez");
+        table.put("bender", "rodriguez");
+
+        assertEquals(table.length(), oldLength + 3); // more like an assumption
+        int i = table.indexOf("bender", "rodriguez");
+        assertEquals(oldLength + 1, i);
+    }
+
+    @Test
+    public void lowerIndexPriority2() {
+        HeaderTable table = new HeaderTable(256);
+        int oldLength = table.length();
+        int idx = rnd.nextInt(oldLength) + 1;
+        HeaderField f = table.get(idx);
+        table.put(f.name, f.value);
+        assertEquals(table.length(), oldLength + 1);
+        int i = table.indexOf(f.name, f.value);
+        assertEquals(idx, i);
+    }
+
+    // TODO: negative indexes check
+    // TODO: ensure full table clearance when adding huge header field
+    // TODO: ensure eviction deletes minimum needed entries, not more
+
+    @Test
+    public void fifo() {
+        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
+        // Let's add a series of header fields
+        int NUM_HEADERS = 32;
+        for (int i = 1; i <= NUM_HEADERS; i++) {
+            String s = String.valueOf(i);
+            t.put(s, s);
+        }
+        // They MUST appear in a FIFO order:
+        //   newer entries are at lower indexes
+        //   older entries are at higher indexes
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            HeaderField f = t.get(STATIC_TABLE_LENGTH + j);
+            int actualName = Integer.parseInt(f.name);
+            int expectedName = NUM_HEADERS - j + 1;
+            assertEquals(expectedName, actualName);
+        }
+        // Entries MUST be evicted in the order they were added:
+        //   the newer the entry the later it is evicted
+        for (int k = 1; k <= NUM_HEADERS; k++) {
+            HeaderField f = t.evictEntry();
+            assertEquals(String.valueOf(k), f.name);
+        }
+    }
+
+    @Test
+    public void indexOf() {
+        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
+        // Let's put a series of header fields
+        int NUM_HEADERS = 32;
+        for (int i = 1; i <= NUM_HEADERS; i++) {
+            String s = String.valueOf(i);
+            t.put(s, s);
+        }
+        // and verify indexOf (reverse lookup) returns correct indexes for
+        // full lookup
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            String s = String.valueOf(j);
+            int actualIndex = t.indexOf(s, s);
+            int expectedIndex = STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1;
+            assertEquals(expectedIndex, actualIndex);
+        }
+        // as well as for just a name lookup
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            String s = String.valueOf(j);
+            int actualIndex = t.indexOf(s, "blah");
+            int expectedIndex = -(STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1);
+            assertEquals(expectedIndex, actualIndex);
+        }
+        // lookup for non-existent name returns 0
+        assertEquals(0, t.indexOf("chupacabra", "1"));
+    }
+
+    @Test
+    public void testToString() {
+        testToString0();
+    }
+
+    @Test
+    public void testToStringDifferentLocale() {
+        Locale.setDefault(Locale.FRENCH);
+        String s = format("%.1f", 3.1);
+        assertEquals("3,1", s); // assumption of the test, otherwise the test is useless
+        testToString0();
+    }
+
+    private void testToString0() {
+        HeaderTable table = new HeaderTable(0);
+        {
+            table.setMaxSize(2048);
+            String expected =
+                    format("entries: %d; used %s/%s (%.1f%%)", 0, 0, 2048, 0.0);
+            assertEquals(expected, table.toString());
+        }
+
+        {
+            String name = "custom-name";
+            String value = "custom-value";
+            int size = 512;
+
+            table.setMaxSize(size);
+            table.put(name, value);
+            String s = table.toString();
+
+            int used = name.length() + value.length() + 32;
+            double ratio = used * 100.0 / size;
+
+            String expected =
+                    format("entries: 1; used %s/%s (%.1f%%)", used, size, ratio);
+            assertEquals(expected, s);
+        }
+
+        {
+            table.setMaxSize(78);
+            table.put(":method", "");
+            table.put(":status", "");
+            String s = table.toString();
+            String expected =
+                    format("entries: %d; used %s/%s (%.1f%%)", 2, 78, 78, 100.0);
+            assertEquals(expected, s);
+        }
+    }
+
+    @Test
+    public void stateString() {
+        HeaderTable table = new HeaderTable(256);
+        table.put("custom-key", "custom-header");
+        // @formatter:off
+        assertEquals("[  1] (s =  55) custom-key: custom-header\n" +
+                     "      Table size:  55", table.getStateString());
+        // @formatter:on
+    }
+
+    private static Map<Integer, HeaderField> createStaticEntries() {
+        Pattern line = Pattern.compile(
+                "\\|\\s*(?<index>\\d+?)\\s*\\|\\s*(?<name>.+?)\\s*\\|\\s*(?<value>.*?)\\s*\\|");
+        Matcher m = line.matcher(SPEC);
+        Map<Integer, HeaderField> result = new HashMap<>();
+        while (m.find()) {
+            int index = Integer.parseInt(m.group("index"));
+            String name = m.group("name");
+            String value = m.group("value");
+            HeaderField f = new HeaderField(name, value);
+            result.put(index, f);
+        }
+        return Collections.unmodifiableMap(result); // lol
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/HuffmanTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.Integer.parseInt;
+import static org.testng.Assert.*;
+
+public final class HuffmanTest {
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-B
+    //
+    private static final String SPEC =
+            // @formatter:off
+     "                          code as bits                 as hex   len\n" +
+     "        sym              aligned to MSB                aligned   in\n" +
+     "                                                       to LSB   bits\n" +
+     "       (  0)  |11111111|11000                             1ff8  [13]\n" +
+     "       (  1)  |11111111|11111111|1011000                7fffd8  [23]\n" +
+     "       (  2)  |11111111|11111111|11111110|0010         fffffe2  [28]\n" +
+     "       (  3)  |11111111|11111111|11111110|0011         fffffe3  [28]\n" +
+     "       (  4)  |11111111|11111111|11111110|0100         fffffe4  [28]\n" +
+     "       (  5)  |11111111|11111111|11111110|0101         fffffe5  [28]\n" +
+     "       (  6)  |11111111|11111111|11111110|0110         fffffe6  [28]\n" +
+     "       (  7)  |11111111|11111111|11111110|0111         fffffe7  [28]\n" +
+     "       (  8)  |11111111|11111111|11111110|1000         fffffe8  [28]\n" +
+     "       (  9)  |11111111|11111111|11101010               ffffea  [24]\n" +
+     "       ( 10)  |11111111|11111111|11111111|111100      3ffffffc  [30]\n" +
+     "       ( 11)  |11111111|11111111|11111110|1001         fffffe9  [28]\n" +
+     "       ( 12)  |11111111|11111111|11111110|1010         fffffea  [28]\n" +
+     "       ( 13)  |11111111|11111111|11111111|111101      3ffffffd  [30]\n" +
+     "       ( 14)  |11111111|11111111|11111110|1011         fffffeb  [28]\n" +
+     "       ( 15)  |11111111|11111111|11111110|1100         fffffec  [28]\n" +
+     "       ( 16)  |11111111|11111111|11111110|1101         fffffed  [28]\n" +
+     "       ( 17)  |11111111|11111111|11111110|1110         fffffee  [28]\n" +
+     "       ( 18)  |11111111|11111111|11111110|1111         fffffef  [28]\n" +
+     "       ( 19)  |11111111|11111111|11111111|0000         ffffff0  [28]\n" +
+     "       ( 20)  |11111111|11111111|11111111|0001         ffffff1  [28]\n" +
+     "       ( 21)  |11111111|11111111|11111111|0010         ffffff2  [28]\n" +
+     "       ( 22)  |11111111|11111111|11111111|111110      3ffffffe  [30]\n" +
+     "       ( 23)  |11111111|11111111|11111111|0011         ffffff3  [28]\n" +
+     "       ( 24)  |11111111|11111111|11111111|0100         ffffff4  [28]\n" +
+     "       ( 25)  |11111111|11111111|11111111|0101         ffffff5  [28]\n" +
+     "       ( 26)  |11111111|11111111|11111111|0110         ffffff6  [28]\n" +
+     "       ( 27)  |11111111|11111111|11111111|0111         ffffff7  [28]\n" +
+     "       ( 28)  |11111111|11111111|11111111|1000         ffffff8  [28]\n" +
+     "       ( 29)  |11111111|11111111|11111111|1001         ffffff9  [28]\n" +
+     "       ( 30)  |11111111|11111111|11111111|1010         ffffffa  [28]\n" +
+     "       ( 31)  |11111111|11111111|11111111|1011         ffffffb  [28]\n" +
+     "   ' ' ( 32)  |010100                                       14  [ 6]\n" +
+     "   '!' ( 33)  |11111110|00                                 3f8  [10]\n" +
+     "  '\"' ( 34)  |11111110|01                                 3f9  [10]\n" +
+     "   '#' ( 35)  |11111111|1010                               ffa  [12]\n" +
+     "   '$' ( 36)  |11111111|11001                             1ff9  [13]\n" +
+     "   '%' ( 37)  |010101                                       15  [ 6]\n" +
+     "   '&' ( 38)  |11111000                                     f8  [ 8]\n" +
+     "   ''' ( 39)  |11111111|010                                7fa  [11]\n" +
+     "   '(' ( 40)  |11111110|10                                 3fa  [10]\n" +
+     "   ')' ( 41)  |11111110|11                                 3fb  [10]\n" +
+     "   '*' ( 42)  |11111001                                     f9  [ 8]\n" +
+     "   '+' ( 43)  |11111111|011                                7fb  [11]\n" +
+     "   ',' ( 44)  |11111010                                     fa  [ 8]\n" +
+     "   '-' ( 45)  |010110                                       16  [ 6]\n" +
+     "   '.' ( 46)  |010111                                       17  [ 6]\n" +
+     "   '/' ( 47)  |011000                                       18  [ 6]\n" +
+     "   '0' ( 48)  |00000                                         0  [ 5]\n" +
+     "   '1' ( 49)  |00001                                         1  [ 5]\n" +
+     "   '2' ( 50)  |00010                                         2  [ 5]\n" +
+     "   '3' ( 51)  |011001                                       19  [ 6]\n" +
+     "   '4' ( 52)  |011010                                       1a  [ 6]\n" +
+     "   '5' ( 53)  |011011                                       1b  [ 6]\n" +
+     "   '6' ( 54)  |011100                                       1c  [ 6]\n" +
+     "   '7' ( 55)  |011101                                       1d  [ 6]\n" +
+     "   '8' ( 56)  |011110                                       1e  [ 6]\n" +
+     "   '9' ( 57)  |011111                                       1f  [ 6]\n" +
+     "   ':' ( 58)  |1011100                                      5c  [ 7]\n" +
+     "   ';' ( 59)  |11111011                                     fb  [ 8]\n" +
+     "   '<' ( 60)  |11111111|1111100                           7ffc  [15]\n" +
+     "   '=' ( 61)  |100000                                       20  [ 6]\n" +
+     "   '>' ( 62)  |11111111|1011                               ffb  [12]\n" +
+     "   '?' ( 63)  |11111111|00                                 3fc  [10]\n" +
+     "   '@' ( 64)  |11111111|11010                             1ffa  [13]\n" +
+     "   'A' ( 65)  |100001                                       21  [ 6]\n" +
+     "   'B' ( 66)  |1011101                                      5d  [ 7]\n" +
+     "   'C' ( 67)  |1011110                                      5e  [ 7]\n" +
+     "   'D' ( 68)  |1011111                                      5f  [ 7]\n" +
+     "   'E' ( 69)  |1100000                                      60  [ 7]\n" +
+     "   'F' ( 70)  |1100001                                      61  [ 7]\n" +
+     "   'G' ( 71)  |1100010                                      62  [ 7]\n" +
+     "   'H' ( 72)  |1100011                                      63  [ 7]\n" +
+     "   'I' ( 73)  |1100100                                      64  [ 7]\n" +
+     "   'J' ( 74)  |1100101                                      65  [ 7]\n" +
+     "   'K' ( 75)  |1100110                                      66  [ 7]\n" +
+     "   'L' ( 76)  |1100111                                      67  [ 7]\n" +
+     "   'M' ( 77)  |1101000                                      68  [ 7]\n" +
+     "   'N' ( 78)  |1101001                                      69  [ 7]\n" +
+     "   'O' ( 79)  |1101010                                      6a  [ 7]\n" +
+     "   'P' ( 80)  |1101011                                      6b  [ 7]\n" +
+     "   'Q' ( 81)  |1101100                                      6c  [ 7]\n" +
+     "   'R' ( 82)  |1101101                                      6d  [ 7]\n" +
+     "   'S' ( 83)  |1101110                                      6e  [ 7]\n" +
+     "   'T' ( 84)  |1101111                                      6f  [ 7]\n" +
+     "   'U' ( 85)  |1110000                                      70  [ 7]\n" +
+     "   'V' ( 86)  |1110001                                      71  [ 7]\n" +
+     "   'W' ( 87)  |1110010                                      72  [ 7]\n" +
+     "   'X' ( 88)  |11111100                                     fc  [ 8]\n" +
+     "   'Y' ( 89)  |1110011                                      73  [ 7]\n" +
+     "   'Z' ( 90)  |11111101                                     fd  [ 8]\n" +
+     "   '[' ( 91)  |11111111|11011                             1ffb  [13]\n" +
+     "  '\\' ( 92)  |11111111|11111110|000                     7fff0  [19]\n" +
+     "   ']' ( 93)  |11111111|11100                             1ffc  [13]\n" +
+     "   '^' ( 94)  |11111111|111100                            3ffc  [14]\n" +
+     "   '_' ( 95)  |100010                                       22  [ 6]\n" +
+     "   '`' ( 96)  |11111111|1111101                           7ffd  [15]\n" +
+     "   'a' ( 97)  |00011                                         3  [ 5]\n" +
+     "   'b' ( 98)  |100011                                       23  [ 6]\n" +
+     "   'c' ( 99)  |00100                                         4  [ 5]\n" +
+     "   'd' (100)  |100100                                       24  [ 6]\n" +
+     "   'e' (101)  |00101                                         5  [ 5]\n" +
+     "   'f' (102)  |100101                                       25  [ 6]\n" +
+     "   'g' (103)  |100110                                       26  [ 6]\n" +
+     "   'h' (104)  |100111                                       27  [ 6]\n" +
+     "   'i' (105)  |00110                                         6  [ 5]\n" +
+     "   'j' (106)  |1110100                                      74  [ 7]\n" +
+     "   'k' (107)  |1110101                                      75  [ 7]\n" +
+     "   'l' (108)  |101000                                       28  [ 6]\n" +
+     "   'm' (109)  |101001                                       29  [ 6]\n" +
+     "   'n' (110)  |101010                                       2a  [ 6]\n" +
+     "   'o' (111)  |00111                                         7  [ 5]\n" +
+     "   'p' (112)  |101011                                       2b  [ 6]\n" +
+     "   'q' (113)  |1110110                                      76  [ 7]\n" +
+     "   'r' (114)  |101100                                       2c  [ 6]\n" +
+     "   's' (115)  |01000                                         8  [ 5]\n" +
+     "   't' (116)  |01001                                         9  [ 5]\n" +
+     "   'u' (117)  |101101                                       2d  [ 6]\n" +
+     "   'v' (118)  |1110111                                      77  [ 7]\n" +
+     "   'w' (119)  |1111000                                      78  [ 7]\n" +
+     "   'x' (120)  |1111001                                      79  [ 7]\n" +
+     "   'y' (121)  |1111010                                      7a  [ 7]\n" +
+     "   'z' (122)  |1111011                                      7b  [ 7]\n" +
+     "   '{' (123)  |11111111|1111110                           7ffe  [15]\n" +
+     "   '|' (124)  |11111111|100                                7fc  [11]\n" +
+     "   '}' (125)  |11111111|111101                            3ffd  [14]\n" +
+     "   '~' (126)  |11111111|11101                             1ffd  [13]\n" +
+     "       (127)  |11111111|11111111|11111111|1100         ffffffc  [28]\n" +
+     "       (128)  |11111111|11111110|0110                    fffe6  [20]\n" +
+     "       (129)  |11111111|11111111|010010                 3fffd2  [22]\n" +
+     "       (130)  |11111111|11111110|0111                    fffe7  [20]\n" +
+     "       (131)  |11111111|11111110|1000                    fffe8  [20]\n" +
+     "       (132)  |11111111|11111111|010011                 3fffd3  [22]\n" +
+     "       (133)  |11111111|11111111|010100                 3fffd4  [22]\n" +
+     "       (134)  |11111111|11111111|010101                 3fffd5  [22]\n" +
+     "       (135)  |11111111|11111111|1011001                7fffd9  [23]\n" +
+     "       (136)  |11111111|11111111|010110                 3fffd6  [22]\n" +
+     "       (137)  |11111111|11111111|1011010                7fffda  [23]\n" +
+     "       (138)  |11111111|11111111|1011011                7fffdb  [23]\n" +
+     "       (139)  |11111111|11111111|1011100                7fffdc  [23]\n" +
+     "       (140)  |11111111|11111111|1011101                7fffdd  [23]\n" +
+     "       (141)  |11111111|11111111|1011110                7fffde  [23]\n" +
+     "       (142)  |11111111|11111111|11101011               ffffeb  [24]\n" +
+     "       (143)  |11111111|11111111|1011111                7fffdf  [23]\n" +
+     "       (144)  |11111111|11111111|11101100               ffffec  [24]\n" +
+     "       (145)  |11111111|11111111|11101101               ffffed  [24]\n" +
+     "       (146)  |11111111|11111111|010111                 3fffd7  [22]\n" +
+     "       (147)  |11111111|11111111|1100000                7fffe0  [23]\n" +
+     "       (148)  |11111111|11111111|11101110               ffffee  [24]\n" +
+     "       (149)  |11111111|11111111|1100001                7fffe1  [23]\n" +
+     "       (150)  |11111111|11111111|1100010                7fffe2  [23]\n" +
+     "       (151)  |11111111|11111111|1100011                7fffe3  [23]\n" +
+     "       (152)  |11111111|11111111|1100100                7fffe4  [23]\n" +
+     "       (153)  |11111111|11111110|11100                  1fffdc  [21]\n" +
+     "       (154)  |11111111|11111111|011000                 3fffd8  [22]\n" +
+     "       (155)  |11111111|11111111|1100101                7fffe5  [23]\n" +
+     "       (156)  |11111111|11111111|011001                 3fffd9  [22]\n" +
+     "       (157)  |11111111|11111111|1100110                7fffe6  [23]\n" +
+     "       (158)  |11111111|11111111|1100111                7fffe7  [23]\n" +
+     "       (159)  |11111111|11111111|11101111               ffffef  [24]\n" +
+     "       (160)  |11111111|11111111|011010                 3fffda  [22]\n" +
+     "       (161)  |11111111|11111110|11101                  1fffdd  [21]\n" +
+     "       (162)  |11111111|11111110|1001                    fffe9  [20]\n" +
+     "       (163)  |11111111|11111111|011011                 3fffdb  [22]\n" +
+     "       (164)  |11111111|11111111|011100                 3fffdc  [22]\n" +
+     "       (165)  |11111111|11111111|1101000                7fffe8  [23]\n" +
+     "       (166)  |11111111|11111111|1101001                7fffe9  [23]\n" +
+     "       (167)  |11111111|11111110|11110                  1fffde  [21]\n" +
+     "       (168)  |11111111|11111111|1101010                7fffea  [23]\n" +
+     "       (169)  |11111111|11111111|011101                 3fffdd  [22]\n" +
+     "       (170)  |11111111|11111111|011110                 3fffde  [22]\n" +
+     "       (171)  |11111111|11111111|11110000               fffff0  [24]\n" +
+     "       (172)  |11111111|11111110|11111                  1fffdf  [21]\n" +
+     "       (173)  |11111111|11111111|011111                 3fffdf  [22]\n" +
+     "       (174)  |11111111|11111111|1101011                7fffeb  [23]\n" +
+     "       (175)  |11111111|11111111|1101100                7fffec  [23]\n" +
+     "       (176)  |11111111|11111111|00000                  1fffe0  [21]\n" +
+     "       (177)  |11111111|11111111|00001                  1fffe1  [21]\n" +
+     "       (178)  |11111111|11111111|100000                 3fffe0  [22]\n" +
+     "       (179)  |11111111|11111111|00010                  1fffe2  [21]\n" +
+     "       (180)  |11111111|11111111|1101101                7fffed  [23]\n" +
+     "       (181)  |11111111|11111111|100001                 3fffe1  [22]\n" +
+     "       (182)  |11111111|11111111|1101110                7fffee  [23]\n" +
+     "       (183)  |11111111|11111111|1101111                7fffef  [23]\n" +
+     "       (184)  |11111111|11111110|1010                    fffea  [20]\n" +
+     "       (185)  |11111111|11111111|100010                 3fffe2  [22]\n" +
+     "       (186)  |11111111|11111111|100011                 3fffe3  [22]\n" +
+     "       (187)  |11111111|11111111|100100                 3fffe4  [22]\n" +
+     "       (188)  |11111111|11111111|1110000                7ffff0  [23]\n" +
+     "       (189)  |11111111|11111111|100101                 3fffe5  [22]\n" +
+     "       (190)  |11111111|11111111|100110                 3fffe6  [22]\n" +
+     "       (191)  |11111111|11111111|1110001                7ffff1  [23]\n" +
+     "       (192)  |11111111|11111111|11111000|00           3ffffe0  [26]\n" +
+     "       (193)  |11111111|11111111|11111000|01           3ffffe1  [26]\n" +
+     "       (194)  |11111111|11111110|1011                    fffeb  [20]\n" +
+     "       (195)  |11111111|11111110|001                     7fff1  [19]\n" +
+     "       (196)  |11111111|11111111|100111                 3fffe7  [22]\n" +
+     "       (197)  |11111111|11111111|1110010                7ffff2  [23]\n" +
+     "       (198)  |11111111|11111111|101000                 3fffe8  [22]\n" +
+     "       (199)  |11111111|11111111|11110110|0            1ffffec  [25]\n" +
+     "       (200)  |11111111|11111111|11111000|10           3ffffe2  [26]\n" +
+     "       (201)  |11111111|11111111|11111000|11           3ffffe3  [26]\n" +
+     "       (202)  |11111111|11111111|11111001|00           3ffffe4  [26]\n" +
+     "       (203)  |11111111|11111111|11111011|110          7ffffde  [27]\n" +
+     "       (204)  |11111111|11111111|11111011|111          7ffffdf  [27]\n" +
+     "       (205)  |11111111|11111111|11111001|01           3ffffe5  [26]\n" +
+     "       (206)  |11111111|11111111|11110001               fffff1  [24]\n" +
+     "       (207)  |11111111|11111111|11110110|1            1ffffed  [25]\n" +
+     "       (208)  |11111111|11111110|010                     7fff2  [19]\n" +
+     "       (209)  |11111111|11111111|00011                  1fffe3  [21]\n" +
+     "       (210)  |11111111|11111111|11111001|10           3ffffe6  [26]\n" +
+     "       (211)  |11111111|11111111|11111100|000          7ffffe0  [27]\n" +
+     "       (212)  |11111111|11111111|11111100|001          7ffffe1  [27]\n" +
+     "       (213)  |11111111|11111111|11111001|11           3ffffe7  [26]\n" +
+     "       (214)  |11111111|11111111|11111100|010          7ffffe2  [27]\n" +
+     "       (215)  |11111111|11111111|11110010               fffff2  [24]\n" +
+     "       (216)  |11111111|11111111|00100                  1fffe4  [21]\n" +
+     "       (217)  |11111111|11111111|00101                  1fffe5  [21]\n" +
+     "       (218)  |11111111|11111111|11111010|00           3ffffe8  [26]\n" +
+     "       (219)  |11111111|11111111|11111010|01           3ffffe9  [26]\n" +
+     "       (220)  |11111111|11111111|11111111|1101         ffffffd  [28]\n" +
+     "       (221)  |11111111|11111111|11111100|011          7ffffe3  [27]\n" +
+     "       (222)  |11111111|11111111|11111100|100          7ffffe4  [27]\n" +
+     "       (223)  |11111111|11111111|11111100|101          7ffffe5  [27]\n" +
+     "       (224)  |11111111|11111110|1100                    fffec  [20]\n" +
+     "       (225)  |11111111|11111111|11110011               fffff3  [24]\n" +
+     "       (226)  |11111111|11111110|1101                    fffed  [20]\n" +
+     "       (227)  |11111111|11111111|00110                  1fffe6  [21]\n" +
+     "       (228)  |11111111|11111111|101001                 3fffe9  [22]\n" +
+     "       (229)  |11111111|11111111|00111                  1fffe7  [21]\n" +
+     "       (230)  |11111111|11111111|01000                  1fffe8  [21]\n" +
+     "       (231)  |11111111|11111111|1110011                7ffff3  [23]\n" +
+     "       (232)  |11111111|11111111|101010                 3fffea  [22]\n" +
+     "       (233)  |11111111|11111111|101011                 3fffeb  [22]\n" +
+     "       (234)  |11111111|11111111|11110111|0            1ffffee  [25]\n" +
+     "       (235)  |11111111|11111111|11110111|1            1ffffef  [25]\n" +
+     "       (236)  |11111111|11111111|11110100               fffff4  [24]\n" +
+     "       (237)  |11111111|11111111|11110101               fffff5  [24]\n" +
+     "       (238)  |11111111|11111111|11111010|10           3ffffea  [26]\n" +
+     "       (239)  |11111111|11111111|1110100                7ffff4  [23]\n" +
+     "       (240)  |11111111|11111111|11111010|11           3ffffeb  [26]\n" +
+     "       (241)  |11111111|11111111|11111100|110          7ffffe6  [27]\n" +
+     "       (242)  |11111111|11111111|11111011|00           3ffffec  [26]\n" +
+     "       (243)  |11111111|11111111|11111011|01           3ffffed  [26]\n" +
+     "       (244)  |11111111|11111111|11111100|111          7ffffe7  [27]\n" +
+     "       (245)  |11111111|11111111|11111101|000          7ffffe8  [27]\n" +
+     "       (246)  |11111111|11111111|11111101|001          7ffffe9  [27]\n" +
+     "       (247)  |11111111|11111111|11111101|010          7ffffea  [27]\n" +
+     "       (248)  |11111111|11111111|11111101|011          7ffffeb  [27]\n" +
+     "       (249)  |11111111|11111111|11111111|1110         ffffffe  [28]\n" +
+     "       (250)  |11111111|11111111|11111101|100          7ffffec  [27]\n" +
+     "       (251)  |11111111|11111111|11111101|101          7ffffed  [27]\n" +
+     "       (252)  |11111111|11111111|11111101|110          7ffffee  [27]\n" +
+     "       (253)  |11111111|11111111|11111101|111          7ffffef  [27]\n" +
+     "       (254)  |11111111|11111111|11111110|000          7fffff0  [27]\n" +
+     "       (255)  |11111111|11111111|11111011|10           3ffffee  [26]\n" +
+     "   EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]";
+    // @formatter:on
+
+    @Test
+    public void read_table() {
+        Pattern line = Pattern.compile(
+                "\\(\\s*(?<ascii>\\d+)\\s*\\)\\s*(?<binary>(\\|(0|1)+)+)\\s*" +
+                        "(?<hex>[0-9a-zA-Z]+)\\s*\\[\\s*(?<len>\\d+)\\s*\\]");
+        Matcher m = line.matcher(SPEC);
+        int i = 0;
+        while (m.find()) {
+            String ascii = m.group("ascii");
+            String binary = m.group("binary").replaceAll("\\|", "");
+            String hex = m.group("hex");
+            String len = m.group("len");
+
+            // Several sanity checks for the data read from the table, just to
+            // make sure what we read makes sense
+            assertEquals(parseInt(len), binary.length());
+            assertEquals(parseInt(binary, 2), parseInt(hex, 16));
+
+            int expected = parseInt(ascii);
+
+            // TODO: find actual eos, do not hardcode it!
+            byte[] bytes = intToBytes(0x3fffffff, 30,
+                    parseInt(hex, 16), parseInt(len));
+
+            StringBuilder actual = new StringBuilder();
+            Huffman.Reader t = new Huffman.Reader();
+            t.read(ByteBuffer.wrap(bytes), actual, false, true);
+
+            // What has been read MUST represent a single symbol
+            assertEquals(actual.length(), 1, "ascii: " + ascii);
+
+            // It's a lot more visual to compare char as codes rather than
+            // characters (as some of them might not be visible)
+            assertEquals(actual.charAt(0), expected);
+            i++;
+        }
+        assertEquals(i, 257); // 256 + EOS
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.1
+    //
+    @Test
+    public void read_1() {
+        read("f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com");
+    }
+
+    @Test
+    public void write_1() {
+        write("www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.2
+    //
+    @Test
+    public void read_2() {
+        read("a8eb 1064 9cbf", "no-cache");
+    }
+
+    @Test
+    public void write_2() {
+        write("no-cache", "a8eb 1064 9cbf");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
+    //
+    @Test
+    public void read_3() {
+        read("25a8 49e9 5ba9 7d7f", "custom-key");
+    }
+
+    @Test
+    public void write_3() {
+        write("custom-key", "25a8 49e9 5ba9 7d7f");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
+    //
+    @Test
+    public void read_4() {
+        read("25a8 49e9 5bb8 e8b4 bf", "custom-value");
+    }
+
+    @Test
+    public void write_4() {
+        write("custom-value", "25a8 49e9 5bb8 e8b4 bf");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_5() {
+        read("6402", "302");
+    }
+
+    @Test
+    public void write_5() {
+        write("302", "6402");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_6() {
+        read("aec3 771a 4b", "private");
+    }
+
+    @Test
+    public void write_6() {
+        write("private", "aec3 771a 4b");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_7() {
+        read("d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff",
+                "Mon, 21 Oct 2013 20:13:21 GMT");
+    }
+
+    @Test
+    public void write_7() {
+        write("Mon, 21 Oct 2013 20:13:21 GMT",
+                "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_8() {
+        read("9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3",
+                "https://www.example.com");
+    }
+
+    @Test
+    public void write_8() {
+        write("https://www.example.com",
+                "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.2
+    //
+    @Test
+    public void read_9() {
+        read("640e ff", "307");
+    }
+
+    @Test
+    public void write_9() {
+        write("307", "640e ff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_10() {
+        read("d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff",
+                "Mon, 21 Oct 2013 20:13:22 GMT");
+    }
+
+    @Test
+    public void write_10() {
+        write("Mon, 21 Oct 2013 20:13:22 GMT",
+                "d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_11() {
+        read("9bd9 ab", "gzip");
+    }
+
+    @Test
+    public void write_11() {
+        write("gzip", "9bd9 ab");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_12() {
+        read("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 " +
+             "d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 " +
+             "3160 65c0 03ed 4ee5 b106 3d50 07",
+             "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+    }
+
+    @Test
+    public void test_trie_has_no_empty_nodes() {
+        Huffman.Node root = Huffman.INSTANCE.getRoot();
+        Stack<Huffman.Node> backlog = new Stack<>();
+        backlog.push(root);
+        while (!backlog.isEmpty()) {
+            Huffman.Node n = backlog.pop();
+            // The only type of nodes we couldn't possibly catch during
+            // construction is an empty node: no children and no char
+            if (n.left != null) {
+                backlog.push(n.left);
+            }
+            if (n.right != null) {
+                backlog.push(n.right);
+            }
+            assertFalse(!n.charIsSet && n.left == null && n.right == null,
+                    "Empty node in the trie");
+        }
+    }
+
+    @Test
+    public void test_trie_has_257_nodes() {
+        int count = 0;
+        Huffman.Node root = Huffman.INSTANCE.getRoot();
+        Stack<Huffman.Node> backlog = new Stack<>();
+        backlog.push(root);
+        while (!backlog.isEmpty()) {
+            Huffman.Node n = backlog.pop();
+            if (n.left != null) {
+                backlog.push(n.left);
+            }
+            if (n.right != null) {
+                backlog.push(n.right);
+            }
+            if (n.isLeaf()) {
+                count++;
+            }
+        }
+        assertEquals(count, 257);
+    }
+
+    @Test
+    public void cant_encode_outside_byte() {
+        TestHelper.Block<Object> coding =
+                () -> new Huffman.Writer()
+                        .from(((char) 256) + "", 0, 1)
+                        .write(ByteBuffer.allocate(1));
+        RuntimeException e =
+                TestHelper.assertVoidThrows(RuntimeException.class, coding);
+        TestHelper.assertExceptionMessageContains(e, "char");
+    }
+
+    private static void read(String hexdump, String decoded) {
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+        Appendable actual = new StringBuilder();
+        new Huffman.Reader().read(source, actual, true);
+        assertEquals(actual.toString(), decoded);
+    }
+
+    private static void write(String decoded, String hexdump) {
+        int n = Huffman.INSTANCE.lengthOf(decoded);
+        ByteBuffer destination = ByteBuffer.allocate(n); // Extra margin (1) to test having more bytes in the destination than needed is ok
+        Huffman.Writer writer = new Huffman.Writer();
+        BuffersTestingKit.forEachSplit(destination, byteBuffers -> {
+            writer.from(decoded, 0, decoded.length());
+            boolean written = false;
+            for (ByteBuffer b : byteBuffers) {
+                int pos = b.position();
+                written = writer.write(b);
+                b.position(pos);
+            }
+            assertTrue(written);
+            ByteBuffer concated = BuffersTestingKit.concat(byteBuffers);
+            String actual = SpecHelper.toHexdump(concated);
+            assertEquals(actual, hexdump);
+            writer.reset();
+        });
+    }
+
+    //
+    // It's not very pretty, yes I know that
+    //
+    //      hex:
+    //
+    //      |31|30|...|N-1|...|01|00|
+    //                  \        /
+    //                  codeLength
+    //
+    //      hex <<= 32 - codeLength; (align to MSB):
+    //
+    //      |31|30|...|32-N|...|01|00|
+    //        \        /
+    //        codeLength
+    //
+    //      EOS:
+    //
+    //      |31|30|...|M-1|...|01|00|
+    //                   \        /
+    //                   eosLength
+    //
+    //      eos <<= 32 - eosLength; (align to MSB):
+    //
+    //      pad with MSBs of EOS:
+    //
+    //      |31|30|...|32-N|32-N-1|...|01|00|
+    //                     |    32|...|
+    //
+    //      Finally, split into byte[]
+    //
+    private byte[] intToBytes(int eos, int eosLength, int hex, int codeLength) {
+        hex <<= 32 - codeLength;
+        eos >>= codeLength - (32 - eosLength);
+        hex |= eos;
+        int n = (int) Math.ceil(codeLength / 8.0);
+        byte[] result = new byte[n];
+        for (int i = 0; i < n; i++) {
+            result[i] = (byte) (hex >> (32 - 8 * (i + 1)));
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/SpecHelper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+//
+// THIS IS NOT A TEST
+//
+public final class SpecHelper {
+
+    private SpecHelper() {
+        throw new AssertionError();
+    }
+
+    public static ByteBuffer toBytes(String hexdump) {
+        Pattern hexByte = Pattern.compile("[0-9a-fA-F]{2}");
+        List<String> bytes = new ArrayList<>();
+        Matcher matcher = hexByte.matcher(hexdump);
+        while (matcher.find()) {
+            bytes.add(matcher.group(0));
+        }
+        ByteBuffer result = ByteBuffer.allocate(bytes.size());
+        for (String f : bytes) {
+            result.put((byte) Integer.parseInt(f, 16));
+        }
+        result.flip();
+        return result;
+    }
+
+    public static String toHexdump(ByteBuffer bb) {
+        List<String> words = new ArrayList<>();
+        int i = 0;
+        while (bb.hasRemaining()) {
+            if (i % 2 == 0) {
+                words.add("");
+            }
+            byte b = bb.get();
+            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
+            words.set(i / 2, words.get(i / 2) + hex);
+            i++;
+        }
+        return words.stream().collect(Collectors.joining(" "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/TestHelper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.hpack;
+
+import org.testng.annotations.Test;
+
+import java.util.Objects;
+import java.util.Random;
+
+public final class TestHelper {
+
+    public static Random newRandom() {
+        long seed = Long.getLong("jdk.test.lib.random.seed", System.currentTimeMillis());
+        System.out.println("new java.util.Random(" + seed + ")");
+        return new Random(seed);
+    }
+
+    public static <T extends Throwable> T assertVoidThrows(Class<T> clazz, Block<?> code) {
+        return assertThrows(clazz, () -> {
+            code.run();
+            return null;
+        });
+    }
+
+    public static <T extends Throwable> T assertThrows(Class<T> clazz, ReturningBlock<?> code) {
+        Objects.requireNonNull(clazz, "clazz == null");
+        Objects.requireNonNull(code, "code == null");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            if (clazz.isInstance(t)) {
+                return clazz.cast(t);
+            }
+            throw new AssertionError("Expected to catch exception of type "
+                    + clazz.getCanonicalName() + ", instead caught "
+                    + t.getClass().getCanonicalName(), t);
+
+        }
+        throw new AssertionError(
+                "Expected to catch exception of type " + clazz.getCanonicalName()
+                        + ", but caught nothing");
+    }
+
+    public static <T> T assertDoesNotThrow(ReturningBlock<T> code) {
+        Objects.requireNonNull(code, "code == null");
+        try {
+            return code.run();
+        } catch (Throwable t) {
+            throw new AssertionError(
+                    "Expected code block to exit normally, instead " +
+                            "caught " + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+    public static void assertVoidDoesNotThrow(Block<?> code) {
+        Objects.requireNonNull(code, "code == null");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            throw new AssertionError(
+                    "Expected code block to exit normally, instead " +
+                            "caught " + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+
+    public static void assertExceptionMessageContains(Throwable t,
+                                                      CharSequence firstSubsequence,
+                                                      CharSequence... others) {
+        assertCharSequenceContains(t.getMessage(), firstSubsequence, others);
+    }
+
+    public static void assertCharSequenceContains(CharSequence s,
+                                                  CharSequence firstSubsequence,
+                                                  CharSequence... others) {
+        if (s == null) {
+            throw new NullPointerException("Exception message is null");
+        }
+        String str = s.toString();
+        String missing = null;
+        if (!str.contains(firstSubsequence.toString())) {
+            missing = firstSubsequence.toString();
+        } else {
+            for (CharSequence o : others) {
+                if (!str.contains(o.toString())) {
+                    missing = o.toString();
+                    break;
+                }
+            }
+        }
+        if (missing != null) {
+            throw new AssertionError("CharSequence '" + s + "'" + " does not "
+                    + "contain subsequence '" + missing + "'");
+        }
+    }
+
+    public interface ReturningBlock<T> {
+        T run() throws Throwable;
+    }
+
+    public interface Block<T> {
+        void run() throws Throwable;
+    }
+
+    // tests
+
+    @Test
+    public void assertThrows() {
+        assertThrows(NullPointerException.class, () -> ((Object) null).toString());
+    }
+
+    @Test
+    public void assertThrowsWrongType() {
+        try {
+            assertThrows(IllegalArgumentException.class, () -> ((Object) null).toString());
+        } catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            String message = e.getMessage();
+            if (cause != null
+                    && cause instanceof NullPointerException
+                    && message != null
+                    && message.contains("instead caught")) {
+                return;
+            }
+        }
+        throw new AssertionError();
+    }
+
+    @Test
+    public void assertThrowsNoneCaught() {
+        try {
+            assertThrows(IllegalArgumentException.class, () -> null);
+        } catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            String message = e.getMessage();
+            if (cause == null
+                    && message != null
+                    && message.contains("but caught nothing")) {
+                return;
+            }
+        }
+        throw new AssertionError();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/BodyInputStream.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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 Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.nio.ByteBuffer;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Queue;
+import jdk.incubator.http.internal.common.Utils;
+import jdk.incubator.http.internal.frame.DataFrame;
+import jdk.incubator.http.internal.frame.Http2Frame;
+import jdk.incubator.http.internal.frame.ResetFrame;
+
+/**
+ * InputStream reads frames off stream q and supplies read demand from any
+ * DataFrames it finds. Window updates are sent back on the connections send
+ * q.
+ */
+class BodyInputStream extends InputStream {
+
+    final Queue<Http2Frame> q;
+    final int streamid;
+    boolean closed;
+    boolean eof;
+    final Http2TestServerConnection conn;
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    BodyInputStream(Queue q, int streamid, Http2TestServerConnection conn) {
+        this.q = q;
+        this.streamid = streamid;
+        this.conn = conn;
+    }
+
+    DataFrame df;
+    ByteBuffer[] buffers;
+    ByteBuffer buffer;
+    int nextIndex = -1;
+
+    private DataFrame getData() throws IOException {
+        if (eof) {
+            return null;
+        }
+        Http2Frame frame;
+        do {
+            frame = q.take();
+            if (frame.type() == ResetFrame.TYPE) {
+                conn.handleStreamReset((ResetFrame) frame); // throws IOException
+            }
+            // ignoring others for now Wupdates handled elsewhere
+            if (frame.type() != DataFrame.TYPE) {
+                System.out.println("Ignoring " + frame.toString() + " CHECK THIS");
+            }
+        } while (frame.type() != DataFrame.TYPE);
+        df = (DataFrame) frame;
+        int len = df.payloadLength();
+        eof = frame.getFlag(DataFrame.END_STREAM);
+        // acknowledge
+        conn.sendWindowUpdates(len, streamid);
+        return (DataFrame) frame;
+    }
+
+    // null return means EOF
+    private ByteBuffer getBuffer() throws IOException {
+        if (buffer == null || !buffer.hasRemaining()) {
+            if (nextIndex == -1 || nextIndex == buffers.length) {
+                DataFrame df = getData();
+                if (df == null) {
+                    return null;
+                }
+                ByteBufferReference[] data = df.getData();
+                int len = Utils.remaining(data);
+                if ((len == 0) && eof) {
+                    return null;
+                }
+
+                buffers = ByteBufferReference.toBuffers(data);
+                nextIndex = 0;
+            }
+            buffer = buffers[nextIndex++];
+        }
+        return buffer;
+    }
+
+    @Override
+    public int read(byte[] buf, int offset, int length) throws IOException {
+        if (closed) {
+            throw new IOException("closed");
+        }
+        ByteBuffer b = getBuffer();
+        if (b == null) {
+            return -1;
+        }
+        int remaining = b.remaining();
+        if (remaining < length) {
+            length = remaining;
+        }
+        b.get(buf, offset, length);
+        return length;
+    }
+
+    byte[] one = new byte[1];
+
+    @Override
+    public int read() throws IOException {
+        int c = read(one, 0, 1);
+        if (c == -1) {
+            return -1;
+        }
+        return one[0];
+    }
+
+    @Override
+    public void close() {
+        // TODO reset this stream
+        closed = true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/BodyOutputStream.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.nio.ByteBuffer;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.common.Queue;
+import jdk.incubator.http.internal.frame.DataFrame;
+
+/**
+ * OutputStream. Incoming window updates handled by the main connection
+ * reader thread.
+ */
+@SuppressWarnings({"rawtypes","unchecked"})
+class BodyOutputStream extends OutputStream {
+    final static byte[] EMPTY_BARRAY = new byte[0];
+
+    final int streamid;
+    int window;
+    boolean closed;
+    boolean goodToGo = false; // not allowed to send until headers sent
+    final Http2TestServerConnection conn;
+    final Queue outputQ;
+
+    BodyOutputStream(int streamid, int initialWindow, Http2TestServerConnection conn) {
+        this.window = initialWindow;
+        this.streamid = streamid;
+        this.conn = conn;
+        this.outputQ = conn.outputQ;
+        conn.registerStreamWindowUpdater(streamid, this::updateWindow);
+    }
+
+    // called from connection reader thread as all incoming window
+    // updates are handled there.
+    synchronized void updateWindow(int update) {
+        window += update;
+        notifyAll();
+    }
+
+    void waitForWindow(int demand) throws InterruptedException {
+        // first wait for the connection window
+        conn.obtainConnectionWindow(demand);
+        // now wait for the stream window
+        synchronized (this) {
+            while (demand > 0) {
+                int n = Math.min(demand, window);
+                demand -= n;
+                window -= n;
+                if (demand > 0) {
+                    wait();
+                }
+            }
+        }
+    }
+
+    void goodToGo() {
+        goodToGo = true;
+    }
+
+    @Override
+    public void write(byte[] buf, int offset, int len) throws IOException {
+        if (closed) {
+            throw new IOException("closed");
+        }
+
+        if (!goodToGo) {
+            throw new IllegalStateException("sendResponseHeaders must be called first");
+        }
+        try {
+            waitForWindow(len);
+            send(buf, offset, len, 0);
+        } catch (InterruptedException ex) {
+            throw new IOException(ex);
+        }
+    }
+
+    private void send(byte[] buf, int offset, int len, int flags) throws IOException {
+        ByteBuffer buffer = ByteBuffer.allocate(len);
+        buffer.put(buf, offset, len);
+        buffer.flip();
+        assert streamid != 0;
+        DataFrame df = new DataFrame(streamid, flags, ByteBufferReference.of(buffer));
+        outputQ.put(df);
+    }
+
+    byte[] one = new byte[1];
+
+    @Override
+    public void write(int b) throws IOException {
+        one[0] = (byte) b;
+        write(one, 0, 1);
+    }
+
+    void closeInternal() {
+        closed = true;
+    }
+
+    @Override
+    public void close() {
+        if (closed) {
+            return;
+        }
+        closed = true;
+        try {
+            send(EMPTY_BARRAY, 0, 0, DataFrame.END_STREAM);
+        } catch (IOException ex) {
+            System.err.println("TestServer: OutputStream.close exception: " + ex);
+            ex.printStackTrace();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/EchoHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+
+public class EchoHandler implements Http2Handler {
+    public EchoHandler() {}
+
+    @Override
+    public void handle(Http2TestExchange t)
+            throws IOException {
+        try {
+            System.err.println("EchoHandler received request to " + t.getRequestURI());
+            InputStream is = t.getRequestBody();
+            HttpHeadersImpl map = t.getRequestHeaders();
+            HttpHeadersImpl map1 = t.getResponseHeaders();
+            map1.addHeader("X-Hello", "world");
+            map1.addHeader("X-Bye", "universe");
+            String fixedrequest = map.firstValue("XFixed").orElse(null);
+            File outfile = File.createTempFile("foo", "bar");
+            //System.err.println ("QQQ = " + outfile.toString());
+            FileOutputStream fos = new FileOutputStream(outfile);
+            int count = (int) is.transferTo(fos);
+            System.err.printf("EchoHandler read %d bytes\n", count);
+            is.close();
+            fos.close();
+            InputStream is1 = new FileInputStream(outfile);
+            OutputStream os = null;
+            // return the number of bytes received (no echo)
+            String summary = map.firstValue("XSummary").orElse(null);
+            if (fixedrequest != null && summary == null) {
+                t.sendResponseHeaders(200, count);
+                os = t.getResponseBody();
+                int count1 = (int)is1.transferTo(os);
+                System.err.printf("EchoHandler wrote %d bytes\n", count1);
+            } else {
+                t.sendResponseHeaders(200, 0);
+                os = t.getResponseBody();
+                int count1 = (int)is1.transferTo(os);
+                System.err.printf("EchoHandler wrote %d bytes\n", count1);
+
+                if (summary != null) {
+                    String s = Integer.toString(count);
+                    os.write(s.getBytes());
+                }
+            }
+            outfile.delete();
+            os.close();
+            is1.close();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw new IOException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/Http2Handler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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;
+
+/**
+ * A handler which is invoked to process HTTP exchanges. Each
+ * HTTP exchange is handled by one of these handlers.
+ */
+public interface Http2Handler {
+    /**
+     * Handles the given request and generate an appropriate response.
+     *
+     * @param exchange the exchange containing the request from the
+     *      client and used to send the response
+     * @throws NullPointerException if exchange is <code>null</code>
+     */
+    void handle (Http2TestExchange exchange) throws IOException;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/Http2TestExchange.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,168 @@
+/*
+ * 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.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.InetSocketAddress;
+import javax.net.ssl.SSLSession;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import jdk.incubator.http.internal.frame.HeaderFrame;
+import jdk.incubator.http.internal.frame.HeadersFrame;
+
+public class Http2TestExchange {
+
+    final HttpHeadersImpl reqheaders;
+    final HttpHeadersImpl rspheaders;
+    final URI uri;
+    final String method;
+    final InputStream is;
+    final BodyOutputStream os;
+    final SSLSession sslSession;
+    final int streamid;
+    final boolean pushAllowed;
+    final Http2TestServerConnection conn;
+    final Http2TestServer server;
+
+    int responseCode = -1;
+    long responseLength;
+
+    Http2TestExchange(int streamid,
+                      String method,
+                      HttpHeadersImpl reqheaders,
+                      HttpHeadersImpl rspheaders,
+                      URI uri,
+                      InputStream is,
+                      SSLSession sslSession,
+                      BodyOutputStream os,
+                      Http2TestServerConnection conn,
+                      boolean pushAllowed) {
+        this.reqheaders = reqheaders;
+        this.rspheaders = rspheaders;
+        this.uri = uri;
+        this.method = method;
+        this.is = is;
+        this.streamid = streamid;
+        this.os = os;
+        this.sslSession = sslSession;
+        this.pushAllowed = pushAllowed;
+        this.conn = conn;
+        this.server = conn.server;
+    }
+
+    public HttpHeadersImpl getRequestHeaders() {
+        return reqheaders;
+    }
+
+    public HttpHeadersImpl getResponseHeaders() {
+        return rspheaders;
+    }
+
+    public URI getRequestURI() {
+        return uri;
+    }
+
+    public String getRequestMethod() {
+        return method;
+    }
+
+    public SSLSession getSSLSession() {
+        return sslSession;
+    }
+
+    public void close() {
+        try {
+            is.close();
+            os.close();
+        } catch (IOException e) {
+            System.err.println("TestServer: HttpExchange.close exception: " + e);
+            e.printStackTrace();
+        }
+    }
+
+    public InputStream getRequestBody() {
+        return is;
+    }
+
+    public OutputStream getResponseBody() {
+        return os;
+    }
+
+    public void sendResponseHeaders(int rCode, long responseLength) throws IOException {
+        this.responseLength = responseLength;
+        if (responseLength > 0 || responseLength < 0) {
+                long clen = responseLength > 0 ? responseLength : 0;
+            rspheaders.setHeader("Content-length", Long.toString(clen));
+        }
+
+        rspheaders.setHeader(":status", Integer.toString(rCode));
+
+        Http2TestServerConnection.ResponseHeaders response
+                = new Http2TestServerConnection.ResponseHeaders(rspheaders);
+        response.streamid(streamid);
+        response.setFlag(HeaderFrame.END_HEADERS);
+        if (responseLength < 0) {
+            response.setFlag(HeadersFrame.END_STREAM);
+            os.closeInternal();
+        }
+        conn.outputQ.put(response);
+        os.goodToGo();
+        System.err.println("Sent response headers " + rCode);
+    }
+
+    public InetSocketAddress getRemoteAddress() {
+        return (InetSocketAddress) conn.socket.getRemoteSocketAddress();
+    }
+
+    public int getResponseCode() {
+        return responseCode;
+    }
+
+    public InetSocketAddress getLocalAddress() {
+        return server.getAddress();
+    }
+
+    public String getProtocol() {
+        return "HTTP/2";
+    }
+
+    public boolean serverPushAllowed() {
+        return pushAllowed;
+    }
+
+    public void serverPush(URI uri, HttpHeadersImpl headers, InputStream content) {
+        OutgoingPushPromise pp = new OutgoingPushPromise(
+                streamid, uri, headers, content);
+        headers.setHeader(":method", "GET");
+        headers.setHeader(":scheme", uri.getScheme());
+        headers.setHeader(":authority", uri.getAuthority());
+        headers.setHeader(":path", uri.getPath());
+        try {
+            conn.outputQ.put(pp);
+            // writeLoop will spin up thread to read the InputStream
+        } catch (IOException ex) {
+            System.err.println("TestServer: pushPromise exception: " + ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/Http2TestServer.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+
+/**
+ * Waits for incoming TCP connections from a client and establishes
+ * a HTTP2 connection. Two threads are created per connection. One for reading
+ * and one for writing. Incoming requests are dispatched to the supplied
+ * Http2Handler on additional threads. All threads
+ * obtained from the supplied ExecutorService.
+ */
+public class Http2TestServer implements AutoCloseable {
+    final ServerSocket server;
+    volatile boolean secure;
+    final ExecutorService exec;
+    volatile boolean stopping = false;
+    final Map<String,Http2Handler> handlers;
+    final SSLContext sslContext;
+    final HashMap<InetSocketAddress,Http2TestServerConnection> connections;
+
+    private static ThreadFactory defaultThreadFac =
+        (Runnable r) -> {
+            Thread t = new Thread(r);
+            t.setName("Test-server-pool");
+            return t;
+        };
+
+
+    private static ExecutorService getDefaultExecutor() {
+        return Executors.newCachedThreadPool(defaultThreadFac);
+    }
+
+    public Http2TestServer(boolean secure, int port) throws Exception {
+        this(secure, port, getDefaultExecutor(), null);
+    }
+
+    public InetSocketAddress getAddress() {
+        return (InetSocketAddress)server.getLocalSocketAddress();
+    }
+
+    public Http2TestServer(boolean secure,
+                           SSLContext context) throws Exception {
+        this(secure, 0, null, context);
+    }
+
+    /**
+     * Create a Http2Server listening on the given port. Currently needs
+     * to know in advance whether incoming connections are plain TCP "h2c"
+     * or TLS "h2"/
+     *
+     * @param secure https or http
+     * @param port listen port
+     * @param exec executor service (cached thread pool is used if null)
+     * @param context the SSLContext used when secure is true
+     */
+    public Http2TestServer(boolean secure,
+                           int port,
+                           ExecutorService exec,
+                           SSLContext context)
+        throws Exception
+    {
+        if (secure) {
+            server = initSecure(port);
+        } else {
+            server = initPlaintext(port);
+        }
+        this.secure = secure;
+        this.exec = exec == null ? getDefaultExecutor() : exec;
+        this.handlers = Collections.synchronizedMap(new HashMap<>());
+        this.sslContext = context;
+        this.connections = new HashMap<>();
+    }
+
+    /**
+     * Adds the given handler for the given path
+     */
+    public void addHandler(Http2Handler handler, String path) {
+        handlers.put(path, handler);
+    }
+
+    Http2Handler getHandlerFor(String path) {
+        if (path == null || path.equals(""))
+            path = "/";
+
+        final String fpath = path;
+        AtomicReference<String> bestMatch = new AtomicReference<>("");
+        AtomicReference<Http2Handler> href = new AtomicReference<>();
+
+        handlers.forEach((key, value) -> {
+            if (fpath.startsWith(key) && key.length() > bestMatch.get().length()) {
+                bestMatch.set(key);
+                href.set(value);
+            }
+        });
+        Http2Handler handler = href.get();
+        if (handler == null)
+            throw new RuntimeException("No handler found for path " + path);
+        System.err.println("Using handler for: " + bestMatch.get());
+        return handler;
+    }
+
+    final ServerSocket initPlaintext(int port) throws Exception {
+        return new ServerSocket(port);
+    }
+
+    public void stop() {
+        // TODO: clean shutdown GoAway
+        stopping = true;
+        for (Http2TestServerConnection connection : connections.values()) {
+            connection.close();
+        }
+        try {
+            server.close();
+        } catch (IOException e) {}
+        exec.shutdownNow();
+    }
+
+
+    final ServerSocket initSecure(int port) throws Exception {
+        ServerSocketFactory fac;
+        if (sslContext != null) {
+            fac = sslContext.getServerSocketFactory();
+        } else {
+            fac = SSLServerSocketFactory.getDefault();
+        }
+        SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(port);
+        SSLParameters sslp = se.getSSLParameters();
+        sslp.setApplicationProtocols(new String[]{"h2"});
+        se.setSSLParameters(sslp);
+        se.setEnabledCipherSuites(se.getSupportedCipherSuites());
+        se.setEnabledProtocols(se.getSupportedProtocols());
+        // other initialisation here
+        return se;
+    }
+
+    /**
+     * Starts a thread which waits for incoming connections.
+     */
+    public void start() {
+        exec.submit(() -> {
+            try {
+                while (!stopping) {
+                    Socket socket = server.accept();
+                    InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress();
+                    Http2TestServerConnection c = new Http2TestServerConnection(this, socket);
+                    connections.put(addr, c);
+                    c.run();
+                }
+            } catch (Throwable e) {
+                if (!stopping) {
+                    System.err.println("TestServer: start exception: " + e);
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+    @Override
+    public void close() throws Exception {
+        stop();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/Http2TestServerConnection.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,782 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.URI;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
+
+import jdk.incubator.http.internal.common.ByteBufferReference;
+import jdk.incubator.http.internal.frame.FramesDecoder;
+
+import jdk.incubator.http.internal.common.BufferHandler;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import jdk.incubator.http.internal.common.Queue;
+import jdk.incubator.http.internal.frame.*;
+import jdk.incubator.http.internal.hpack.Decoder;
+import jdk.incubator.http.internal.hpack.DecodingCallback;
+import jdk.incubator.http.internal.hpack.Encoder;
+import static jdk.incubator.http.internal.frame.SettingsFrame.HEADER_TABLE_SIZE;
+
+/**
+ * Represents one HTTP2 connection, either plaintext upgraded from HTTP/1.1
+ * or HTTPS opened using "h2" ALPN.
+ */
+public class Http2TestServerConnection {
+    final Http2TestServer server;
+    @SuppressWarnings({"rawtypes","unchecked"})
+    final Map<Integer, Queue> streams; // input q per stream
+    final HashSet<Integer> pushStreams;
+    final Queue<Http2Frame> outputQ;
+    volatile int nextstream;
+    final Socket socket;
+    final InputStream is;
+    final OutputStream os;
+    volatile Encoder hpackOut;
+    volatile Decoder hpackIn;
+    volatile SettingsFrame clientSettings;
+    final SettingsFrame serverSettings;
+    final ExecutorService exec;
+    final boolean secure;
+    volatile boolean stopping;
+    volatile int nextPushStreamId = 2;
+
+    final static ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
+    final static byte[] EMPTY_BARRAY = new byte[0];
+
+    final static byte[] clientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes();
+
+    Http2TestServerConnection(Http2TestServer server, Socket socket) throws IOException {
+        System.err.println("TestServer: New connection from " + socket);
+        this.server = server;
+        this.streams = Collections.synchronizedMap(new HashMap<>());
+        this.outputQ = new Queue<>();
+        this.socket = socket;
+        this.serverSettings = SettingsFrame.getDefaultSettings();
+        this.exec = server.exec;
+        this.secure = server.secure;
+        this.pushStreams = new HashSet<>();
+        is = new BufferedInputStream(socket.getInputStream());
+        os = new BufferedOutputStream(socket.getOutputStream());
+    }
+
+    void close() {
+        streams.forEach((i, q) -> {
+            q.close();
+        });
+        stopping = true;
+        try {
+            socket.close();
+            // TODO: put a reset on each stream
+        } catch (IOException e) {
+        }
+    }
+
+    private void readPreface() throws IOException {
+        int len = clientPreface.length;
+        byte[] bytes = new byte[len];
+        is.readNBytes(bytes, 0, len);
+        if (Arrays.compare(clientPreface, bytes) != 0) {
+            throw new IOException("Invalid preface: " + new String(bytes, 0, len));
+        }
+    }
+
+    String doUpgrade() throws IOException {
+        String upgrade = readHttp1Request();
+        String h2c = getHeader(upgrade, "Upgrade");
+        if (h2c == null || !h2c.equals("h2c")) {
+            System.err.println("Server:HEADERS: " + upgrade);
+            throw new IOException("Bad upgrade 1 " + h2c);
+        }
+
+        sendHttp1Response(101, "Switching Protocols", "Connection", "Upgrade",
+                "Upgrade", "h2c");
+
+        sendSettingsFrame();
+        readPreface();
+
+        String clientSettingsString = getHeader(upgrade, "HTTP2-Settings");
+        clientSettings = getSettingsFromString(clientSettingsString);
+
+        return upgrade;
+    }
+
+    /**
+     * Decodes the given, Client, settings payload provided in base64 HTTP1
+     * header value.
+     */
+    private SettingsFrame getSettingsFromString(String s) throws IOException {
+        Base64.Decoder decoder = Base64.getUrlDecoder();
+        byte[] payload = decoder.decode(s);
+        ByteBuffer bb1 = ByteBuffer.wrap(payload);
+        // simulate header of Settings Frame
+        ByteBuffer bb0 = ByteBuffer.wrap(
+                new byte[] {0, 0, (byte)payload.length, 4, 0, 0, 0, 0, 0});
+        List<Http2Frame> frames = new ArrayList<>();
+        FramesDecoder reader = new FramesDecoder(frames::add);
+        reader.decode(ByteBufferReference.of(bb0));
+        reader.decode(ByteBufferReference.of(bb1));
+        if (frames.size()!=1)
+            throw new IOException("Expected 1 frame got "+frames.size()) ;
+        Http2Frame frame = frames.get(0);
+        if (!(frame instanceof SettingsFrame))
+            throw new IOException("Expected SettingsFrame");
+        return (SettingsFrame)frame;
+    }
+
+    void run() throws Exception {
+        String upgrade = null;
+        if (!secure) {
+            upgrade = doUpgrade();
+        } else {
+            readPreface();
+            sendSettingsFrame(true);
+            clientSettings = (SettingsFrame) readFrame();
+            if (clientSettings.getFlag(SettingsFrame.ACK)) {
+                // we received the ack to our frame first
+                clientSettings = (SettingsFrame) readFrame();
+            }
+            nextstream = 1;
+        }
+
+        System.out.println("ServerSettings: " + serverSettings);
+        System.out.println("ClientSettings: " + clientSettings);
+
+        hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
+        hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE));
+
+        if (!secure) {
+            createPrimordialStream(upgrade);
+            nextstream = 3;
+        }
+
+        exec.submit(this::readLoop);
+        exec.submit(this::writeLoop);
+    }
+
+    static class BufferPool implements BufferHandler {
+
+        public void setMinBufferSize(int size) {
+        }
+
+        @Override
+        public ByteBuffer getBuffer() {
+            int size = 32 * 1024;
+            return ByteBuffer.allocate(size);
+        }
+
+        @Override
+        public void returnBuffer(ByteBuffer buffer) {
+        }
+    }
+
+    private void writeFrame(Http2Frame frame) throws IOException {
+        ByteBufferReference[] refs = new FramesEncoder().encodeFrame(frame);
+        //System.err.println("TestServer: Writing frame " + frame.toString());
+        int c = 0;
+        for (ByteBufferReference ref : refs) {
+            ByteBuffer buf = ref.get();
+            byte[] ba = buf.array();
+            int start = buf.arrayOffset() + buf.position();
+            c += buf.remaining();
+            os.write(ba, start, buf.remaining());
+        }
+        os.flush();
+        //System.err.printf("TestServer: wrote %d bytes\n", c);
+    }
+
+    void handleStreamReset(ResetFrame resetFrame) throws IOException {
+        // TODO: cleanup
+        throw new IOException("Stream reset");
+    }
+
+    private void handleCommonFrame(Http2Frame f) throws IOException {
+        if (f instanceof SettingsFrame) {
+            SettingsFrame sf = (SettingsFrame) f;
+            if (sf.getFlag(SettingsFrame.ACK)) // ignore
+            {
+                return;
+            }
+            // otherwise acknowledge it
+            clientSettings = sf;
+            SettingsFrame frame = new SettingsFrame();
+            frame.setFlag(SettingsFrame.ACK);
+            frame.streamid(0);
+            outputQ.put(frame);
+            return;
+        }
+        //System.err.println("TestServer: Received ---> " + f.toString());
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    void sendWindowUpdates(int len, int streamid) throws IOException {
+        if (len == 0)
+            return;
+        WindowUpdateFrame wup = new WindowUpdateFrame(streamid, len);
+        outputQ.put(wup);
+        wup = new WindowUpdateFrame(0 , len);
+        outputQ.put(wup);
+    }
+
+    HttpHeadersImpl decodeHeaders(List<HeaderFrame> frames) {
+        HttpHeadersImpl headers = new HttpHeadersImpl();
+
+        DecodingCallback cb = (name, value) -> {
+            headers.addHeader(name.toString(), value.toString());
+        };
+
+        for (HeaderFrame frame : frames) {
+            ByteBufferReference[] buffers = frame.getHeaderBlock();
+            for (ByteBufferReference buffer : buffers) {
+                hpackIn.decode(buffer.get(), false, cb);
+            }
+        }
+        hpackIn.decode(EMPTY_BUFFER, true, cb);
+        return headers;
+    }
+
+    String getRequestLine(String request) {
+        int eol = request.indexOf(CRLF);
+        return request.substring(0, eol);
+    }
+
+    String getHeaders(String request) {
+        int start = request.indexOf(CRLF);
+        int end = request.indexOf(CRLFCRLF);
+        if (start == -1 || end == -1) {
+            throw new RuntimeException("Malformed request");
+        }
+        return request.substring(start,end);
+    }
+
+    void addHeaders(String headers, HttpHeadersImpl hdrs) {
+        String[] hh = headers.split(CRLF);
+        for (String header : hh) {
+            int colon = header.indexOf(':');
+            if (colon == -1)
+                continue;
+            String name = header.substring(0, colon);
+            String value = header.substring(colon+1);
+            while (value.startsWith(" "))
+                value = value.substring(1);
+            hdrs.addHeader(name, value);
+        }
+    }
+
+    // First stream (1) comes from a plaintext HTTP/1.1 request
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void createPrimordialStream(String request) throws IOException {
+        HttpHeadersImpl headers = new HttpHeadersImpl();
+        String requestLine = getRequestLine(request);
+        String[] tokens = requestLine.split(" ");
+        if (!tokens[2].equals("HTTP/1.1")) {
+            throw new IOException("bad request line");
+        }
+        URI uri = null;
+        try {
+            uri = new URI(tokens[1]);
+        } catch (URISyntaxException e) {
+            throw new IOException(e);
+        }
+        String host = getHeader(request, "Host");
+        if (host == null) {
+            throw new IOException("missing Host");
+        }
+
+        headers.setHeader(":method", tokens[0]);
+        headers.setHeader(":scheme", "http"); // always in this case
+        headers.setHeader(":authority", host);
+        headers.setHeader(":path", uri.getPath());
+        Queue q = new Queue();
+        String body = getRequestBody(request);
+        addHeaders(getHeaders(request), headers);
+        headers.setHeader("Content-length", Integer.toString(body.length()));
+
+        addRequestBodyToQueue(body, q);
+        streams.put(1, q);
+        exec.submit(() -> {
+            handleRequest(headers, q, 1, true /*complete request has been read*/);
+        });
+    }
+
+    // all other streams created here
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void createStream(HeaderFrame frame) throws IOException {
+        List<HeaderFrame> frames = new LinkedList<>();
+        frames.add(frame);
+        int streamid = frame.streamid();
+        if (streamid != nextstream) {
+            throw new IOException("unexpected stream id");
+        }
+        nextstream += 2;
+
+        boolean endStream = false;
+        if (frame.getFlag(HeaderFrame.END_STREAM)) {
+            endStream = true;
+        }
+
+        while (!frame.getFlag(HeaderFrame.END_HEADERS)) {
+            Http2Frame f = readFrame();
+            if (!(f instanceof HeaderFrame)) {
+                handleCommonFrame(f); // should only be error frames
+            } else {
+                frame = (HeaderFrame) f;
+                if (frame.getFlag(HeaderFrame.END_STREAM)) {
+                    endStream = true;
+                }
+                frames.add(frame);
+            }
+        }
+        boolean endStreamReceived = endStream;
+        HttpHeadersImpl headers = decodeHeaders(frames);
+        Queue q = new Queue();
+        streams.put(streamid, q);
+        exec.submit(() -> {
+            handleRequest(headers, q, streamid, endStreamReceived);
+        });
+    }
+
+    // runs in own thread. Handles request from start to finish. Incoming frames
+    // for this stream/request delivered on Q
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void handleRequest(HttpHeadersImpl headers,
+                       Queue queue,
+                       int streamid,
+                       boolean endStreamReceived)
+    {
+        String method = headers.firstValue(":method").orElse("");
+        //System.out.println("method = " + method);
+        String path = headers.firstValue(":path").orElse("");
+        //System.out.println("path = " + path);
+        String scheme = headers.firstValue(":scheme").orElse("");
+        //System.out.println("scheme = " + scheme);
+        String authority = headers.firstValue(":authority").orElse("");
+        //System.out.println("authority = " + authority);
+        System.err.printf("TestServer: %s %s\n", method, path);
+        HttpHeadersImpl rspheaders = new HttpHeadersImpl();
+        int winsize = clientSettings.getParameter(
+                        SettingsFrame.INITIAL_WINDOW_SIZE);
+        //System.err.println ("Stream window size = " + winsize);
+
+        final InputStream bis;
+        if (endStreamReceived) {
+            bis = NullInputStream.INSTANCE;
+        } else {
+            bis = new BodyInputStream(queue, streamid, this);
+        }
+        try (bis;
+             BodyOutputStream bos = new BodyOutputStream(streamid, winsize, this))
+        {
+            String us = scheme + "://" + authority + path;
+            URI uri = new URI(us);
+            boolean pushAllowed = clientSettings.getParameter(SettingsFrame.ENABLE_PUSH) == 1;
+            Http2TestExchange exchange = new Http2TestExchange(streamid, method,
+                    headers, rspheaders, uri, bis, getSSLSession(),
+                    bos, this, pushAllowed);
+
+            // give to user
+            Http2Handler handler = server.getHandlerFor(uri.getPath());
+            handler.handle(exchange);
+
+            // everything happens in the exchange from here. Hopefully will
+            // return though.
+        } catch (Throwable e) {
+            System.err.println("TestServer: handleRequest exception: " + e);
+            e.printStackTrace();
+        }
+    }
+
+    private SSLSession getSSLSession() {
+        if (! (socket instanceof SSLSocket))
+            return null;
+        SSLSocket ssl = (SSLSocket)socket;
+        return ssl.getSession();
+    }
+    // Runs in own thread
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void readLoop() {
+        try {
+            while (!stopping) {
+                Http2Frame frame = readFrame();
+                //System.err.printf("TestServer: received frame %s\n", frame);
+                int stream = frame.streamid();
+                if (stream == 0) {
+                    if (frame.type() == WindowUpdateFrame.TYPE) {
+                        WindowUpdateFrame wup = (WindowUpdateFrame) frame;
+                        updateConnectionWindow(wup.getUpdate());
+                    } else {
+                        // other common frame types
+                        handleCommonFrame(frame);
+                    }
+                } else {
+                    Queue q = streams.get(stream);
+                    if (frame.type() == HeadersFrame.TYPE) {
+                        if (q != null) {
+                            System.err.println("HEADERS frame for existing stream! Error.");
+                            // TODO: close connection
+                            continue;
+                        } else {
+                            createStream((HeadersFrame) frame);
+                        }
+                    } else {
+                        if (q == null && !pushStreams.contains(stream)) {
+                            System.err.printf("Non Headers frame received with"+
+                                " non existing stream (%d) ", frame.streamid());
+                            System.err.println(frame);
+                            continue;
+                        }
+                        if (frame.type() == WindowUpdateFrame.TYPE) {
+                            WindowUpdateFrame wup = (WindowUpdateFrame) frame;
+                            synchronized (updaters) {
+                                Consumer<Integer> r = updaters.get(stream);
+                                r.accept(wup.getUpdate());
+                            }
+                        } else {
+                            q.put(frame);
+                        }
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            if (!stopping) {
+                System.err.println("Http server reader thread shutdown");
+                e.printStackTrace();
+            }
+            close();
+        }
+    }
+
+    ByteBufferReference[] encodeHeaders(HttpHeadersImpl headers) {
+        List<ByteBuffer> buffers = new LinkedList<>();
+
+        ByteBuffer buf = getBuffer();
+        boolean encoded;
+        for (Map.Entry<String, List<String>> entry : headers.map().entrySet()) {
+            List<String> values = entry.getValue();
+            String key = entry.getKey().toLowerCase();
+            for (String value : values) {
+                do {
+                    hpackOut.header(key, value);
+                    encoded = hpackOut.encode(buf);
+                    if (!encoded) {
+                        buf.flip();
+                        buffers.add(buf);
+                        buf = getBuffer();
+                    }
+                } while (!encoded);
+            }
+        }
+        buf.flip();
+        buffers.add(buf);
+        return ByteBufferReference.toReferences(buffers.toArray(bbarray));
+    }
+
+    static void closeIgnore(Closeable c) {
+        try {
+            c.close();
+        } catch (IOException e) {}
+    }
+
+    // Runs in own thread
+    void writeLoop() {
+        try {
+            while (!stopping) {
+                Http2Frame frame = outputQ.take();
+                if (frame instanceof ResponseHeaders) {
+                    ResponseHeaders rh = (ResponseHeaders)frame;
+                    HeadersFrame hf = new HeadersFrame(rh.streamid(), rh.getFlags(), encodeHeaders(rh.headers));
+                    writeFrame(hf);
+                } else if (frame instanceof OutgoingPushPromise) {
+                    handlePush((OutgoingPushPromise)frame);
+                } else
+                    writeFrame(frame);
+            }
+            System.err.println("TestServer: Connection writer stopping");
+        } catch (Throwable e) {
+            e.printStackTrace();
+            /*close();
+            if (!stopping) {
+                e.printStackTrace();
+                System.err.println("TestServer: writeLoop exception: " + e);
+            }*/
+        }
+    }
+
+    private void handlePush(OutgoingPushPromise op) throws IOException {
+        int promisedStreamid = nextPushStreamId;
+        PushPromiseFrame pp = new PushPromiseFrame(op.parentStream, HeaderFrame.END_HEADERS, promisedStreamid, encodeHeaders(op.headers), 0);
+        pushStreams.add(promisedStreamid);
+        nextPushStreamId += 2;
+        pp.streamid(op.parentStream);
+        writeFrame(pp);
+        final InputStream ii = op.is;
+        final BodyOutputStream oo = new BodyOutputStream(
+                promisedStreamid,
+                clientSettings.getParameter(
+                        SettingsFrame.INITIAL_WINDOW_SIZE), this);
+        oo.goodToGo();
+        exec.submit(() -> {
+            try {
+                ResponseHeaders oh = getPushResponse(promisedStreamid);
+                outputQ.put(oh);
+                ii.transferTo(oo);
+            } catch (Throwable ex) {
+                System.err.printf("TestServer: pushing response error: %s\n",
+                        ex.toString());
+            } finally {
+                closeIgnore(ii);
+                closeIgnore(oo);
+            }
+        });
+
+    }
+
+    // returns a minimal response with status 200
+    // that is the response to the push promise just sent
+    private ResponseHeaders getPushResponse(int streamid) {
+        HttpHeadersImpl h = new HttpHeadersImpl();
+        h.addHeader(":status", "200");
+        ResponseHeaders oh = new ResponseHeaders(h);
+        oh.streamid(streamid);
+        oh.setFlag(HeaderFrame.END_HEADERS);
+        return oh;
+    }
+
+    private ByteBuffer getBuffer() {
+        return ByteBuffer.allocate(8 * 1024);
+    }
+
+    private Http2Frame readFrame() throws IOException {
+        byte[] buf = new byte[9];
+        if (is.readNBytes(buf, 0, 9) != 9)
+            throw new IOException("readFrame: connection closed");
+        int len = 0;
+        for (int i = 0; i < 3; i++) {
+            int n = buf[i] & 0xff;
+            //System.err.println("n = " + n);
+            len = (len << 8) + n;
+        }
+        byte[] rest = new byte[len];
+        int n = is.readNBytes(rest, 0, len);
+        if (n != len)
+            throw new IOException("Error reading frame");
+        List<Http2Frame> frames = new ArrayList<>();
+        FramesDecoder reader = new FramesDecoder(frames::add);
+        reader.decode(ByteBufferReference.of(ByteBuffer.wrap(buf)));
+        reader.decode(ByteBufferReference.of(ByteBuffer.wrap(rest)));
+        if (frames.size()!=1)
+            throw new IOException("Expected 1 frame got "+frames.size()) ;
+
+        return frames.get(0);
+    }
+
+    void sendSettingsFrame() throws IOException {
+        sendSettingsFrame(false);
+    }
+
+    void sendSettingsFrame(boolean now) throws IOException {
+        if (now) {
+            writeFrame(serverSettings);
+        } else {
+            outputQ.put(serverSettings);
+        }
+    }
+
+    String readUntil(String end) throws IOException {
+        int number = end.length();
+        int found = 0;
+        StringBuilder sb = new StringBuilder();
+        while (found < number) {
+            char expected = end.charAt(found);
+            int c = is.read();
+            if (c == -1) {
+                throw new IOException("Connection closed");
+            }
+            char c0 = (char) c;
+            sb.append(c0);
+            if (c0 != expected) {
+                found = 0;
+                continue;
+            }
+            found++;
+        }
+        return sb.toString();
+    }
+
+    private int getContentLength(String headers) {
+        return getIntHeader(headers, "Content-length");
+    }
+
+    private int getIntHeader(String headers, String name) {
+        String val = getHeader(headers, name);
+        if (val == null) {
+            return -1;
+        }
+        return Integer.parseInt(val);
+    }
+
+    private String getHeader(String headers, String name) {
+        String headers1 = headers.toLowerCase(); // not efficient
+        name = CRLF + name.toLowerCase();
+        int start = headers1.indexOf(name);
+        if (start == -1) {
+            return null;
+        }
+        start += 2;
+        int end = headers1.indexOf(CRLF, start);
+        String line = headers.substring(start, end);
+        start = line.indexOf(':');
+        if (start == -1) {
+            return null;
+        }
+        return line.substring(start + 1).trim();
+    }
+
+    final static String CRLF = "\r\n";
+    final static String CRLFCRLF = "\r\n\r\n";
+
+    String readHttp1Request() throws IOException {
+        String headers = readUntil(CRLF + CRLF);
+        int clen = getContentLength(headers);
+        // read the content.
+        byte[] buf = new byte[clen];
+        is.readNBytes(buf, 0, clen);
+        String body = new String(buf, StandardCharsets.US_ASCII);
+        return headers + body;
+    }
+
+    void sendHttp1Response(int code, String msg, String... headers) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        sb.append("HTTP/1.1 ")
+                .append(code)
+                .append(' ')
+                .append(msg)
+                .append(CRLF);
+        int numheaders = headers.length;
+        for (int i = 0; i < numheaders; i += 2) {
+            sb.append(headers[i])
+                    .append(": ")
+                    .append(headers[i + 1])
+                    .append(CRLF);
+        }
+        sb.append(CRLF);
+        String s = sb.toString();
+        os.write(s.getBytes("US-ASCII"));
+        os.flush();
+    }
+
+    private void unexpectedFrame(Http2Frame frame) {
+        System.err.println("OOPS. Unexpected");
+        assert false;
+    }
+
+    final static ByteBuffer[] bbarray = new ByteBuffer[0];
+
+    // wrapper around a BlockingQueue that throws an exception when it's closed
+    // Each stream has one of these
+
+    String getRequestBody(String request) {
+        int bodystart = request.indexOf(CRLF+CRLF);
+        String body;
+        if (bodystart == -1)
+            body = "";
+        else
+            body = request.substring(bodystart+4);
+        return body;
+    }
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void addRequestBodyToQueue(String body, Queue q) throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(body.getBytes(StandardCharsets.US_ASCII));
+        DataFrame df = new DataFrame(1, DataFrame.END_STREAM, ByteBufferReference.of(buf));
+        // only used for primordial stream
+        q.put(df);
+    }
+
+    // window updates done in main reader thread because they may
+    // be used to unblock BodyOutputStreams waiting for WUPs
+
+    HashMap<Integer,Consumer<Integer>> updaters = new HashMap<>();
+
+    void registerStreamWindowUpdater(int streamid, Consumer<Integer> r) {
+        synchronized(updaters) {
+            updaters.put(streamid, r);
+        }
+    }
+
+    int sendWindow = 64 * 1024 - 1; // connection level send window
+
+    /**
+     * BodyOutputStreams call this to get the connection window first.
+     *
+     * @param amount
+     */
+    synchronized void obtainConnectionWindow(int amount) throws InterruptedException {
+       while (amount > 0) {
+           int n = Math.min(amount, sendWindow);
+           amount -= n;
+           sendWindow -= n;
+           if (amount > 0)
+               wait();
+       }
+    }
+
+    synchronized void updateConnectionWindow(int amount) {
+        sendWindow += amount;
+        notifyAll();
+    }
+
+    // simplified output headers class. really just a type safe container
+    // for the hashmap.
+
+    static class ResponseHeaders extends Http2Frame {
+        HttpHeadersImpl headers;
+
+        ResponseHeaders(HttpHeadersImpl headers) {
+            super(0, 0);
+            this.headers = headers;
+        }
+
+    }
+
+    static class NullInputStream extends InputStream {
+       static final NullInputStream INSTANCE = new NullInputStream();
+       private NullInputStream() {}
+       public int read()      { return -1; }
+       public int available() { return 0;  }
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/NoBodyHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.*;
+import static java.lang.System.out;
+
+public class NoBodyHandler implements Http2Handler {
+
+    @Override
+    public void handle(Http2TestExchange t) throws IOException {
+        try {
+            out.println("NoBodyHandler received request to " + t.getRequestURI());
+            try (InputStream is = t.getRequestBody()) {
+                byte[] ba = is.readAllBytes();
+                out.println(Thread.currentThread().getName() + ": Read " + ba.length);
+            }
+            t.sendResponseHeaders(200, 0);
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw new IOException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/OutgoingPushPromise.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.net.*;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import jdk.incubator.http.internal.frame.Http2Frame;
+
+// will be converted to a PushPromiseFrame in the writeLoop
+// a thread is then created to produce the DataFrames from the InputStream
+class OutgoingPushPromise extends Http2Frame {
+    final HttpHeadersImpl headers;
+    final URI uri;
+    final InputStream is;
+    final int parentStream; // not the pushed streamid
+
+    public OutgoingPushPromise(int parentStream,
+                               URI uri,
+                               HttpHeadersImpl headers,
+                               InputStream is) {
+        super(0,0);
+        this.uri = uri;
+        this.headers = headers;
+        this.is = is;
+        this.parentStream = parentStream;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/PushHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+
+public class PushHandler implements Http2Handler {
+
+    final Path tempFile;
+    final int loops;
+    final int file_size;
+
+    public PushHandler(int file_size, int loops) throws Exception {
+        tempFile = TestUtil.getAFile(file_size);
+        this.loops = loops;
+        this.file_size = file_size;
+    }
+
+    int invocation = 0;
+
+    public void handle(Http2TestExchange ee) {
+        try {
+            System.err.println ("Server: handle " + ee);
+            invocation++;
+
+            if (ee.serverPushAllowed()) {
+                for (int i=0; i<loops; i++) {
+                    InputStream is = new FileInputStream(tempFile.toFile());
+                    URI u = new URI ("http://www.foo.com/x/y/z/" + Integer.toString(i));
+                    HttpHeadersImpl h = new HttpHeadersImpl();
+                    h.addHeader("X-foo", "bar");
+                    ee.serverPush(u, h, is);
+                }
+                System.err.println ("Server: sent all pushes");
+            }
+            ee.sendResponseHeaders(200, file_size);
+            OutputStream os = ee.getResponseBody();
+            InputStream iis = new FileInputStream(tempFile.toFile());
+            iis.transferTo(os);
+            os.close();
+            iis.close();
+        } catch (Exception ex) {
+            System.err.println ("Server: exception " + ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/RedirectHandler.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.*;
+import java.util.function.Supplier;
+import jdk.incubator.http.internal.common.HttpHeadersImpl;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
+public class RedirectHandler implements Http2Handler {
+
+    final Supplier<String> supplier;
+
+    public RedirectHandler(Supplier<String> redirectSupplier) {
+        supplier = redirectSupplier;
+    }
+
+    static String consume(InputStream is) throws IOException {
+        byte[] b = new byte[1024];
+        int i;
+        StringBuilder sb = new StringBuilder();
+
+        while ((i=is.read(b)) != -1) {
+            sb.append(new String(b, 0, i, ISO_8859_1));
+        }
+        is.close();
+        return sb.toString();
+    }
+
+    @Override
+    public void handle(Http2TestExchange t) throws IOException {
+        try {
+            consume(t.getRequestBody());
+            String location = supplier.get();
+            System.err.println("RedirectHandler received request to " + t.getRequestURI());
+            System.err.println("Redirecting to: " + location);
+            HttpHeadersImpl map1 = t.getResponseHeaders();
+            map1.addHeader("Location", location);
+            t.sendResponseHeaders(301, 0);
+            // return the number of bytes received (no echo)
+            t.close();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw new IOException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/server/TestUtil.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.nio.file.*;
+import java.util.Arrays;
+
+public class TestUtil {
+
+    final static String fileContent = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // repeated
+
+    public static Path getAFile(int size) throws IOException {
+        Path p = tempFile();
+        BufferedWriter writer = Files.newBufferedWriter(p);
+        int len = fileContent.length();
+        int iterations = size / len;
+        int remainder = size - (iterations * len);
+        for (int i=0; i<iterations; i++)
+            writer.write(fileContent, 0, len);
+        writer.write(fileContent, 0, remainder);
+        writer.close();
+        return p;
+    }
+
+    public static Path tempFile() {
+        try {
+            Path p = Files.createTempFile("foo", "test");
+            p.toFile().deleteOnExit();
+            return p;
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    public static Void compareFiles(Path path1, Path path2) {
+        //System.err.printf("Comparing %s and %s\n", path1.toString(), path2.toString());
+        try {
+            long size1 = Files.size(path1);
+            long size2 = Files.size(path2);
+            if (size1 != size2) {
+                String msg = "File sizes do not match " +
+                        Long.toString(size1) + "/" + Long.toString(size2);
+                throw new RuntimeException(msg);
+            }
+            compareContents(path1, path2);
+            return null;
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    static void compareContents(Path path1, Path path2) {
+        try {
+            byte[] b1 = Files.readAllBytes(path1);
+            byte[] b2 = Files.readAllBytes(path2);
+            if (!Arrays.equals(b1, b2))
+                throw new RuntimeException ("Files do not match");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+}
--- a/jdk/test/java/net/httpclient/security/0.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/0.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/1.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/1.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,27 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
+
--- a/jdk/test/java/net/httpclient/security/10.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/10.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -19,3 +19,27 @@
     permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
+
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/11.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/11.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,27 @@
     permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
+
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/12.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/12.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,27 @@
     permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
+
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/14.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/14.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/15.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/15.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -14,7 +14,7 @@
     permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*";
 
     // Test checks for this explicitly
-    permission java.net.RuntimePermission "foobar";
+    permission java.lang.RuntimePermission "foobar";
 };
 
 
@@ -23,3 +23,27 @@
     permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
+
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/2.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/2.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/3.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/3.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/4.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/4.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -22,3 +22,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/5.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/5.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/6.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/6.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/7.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/7.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/8.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/8.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/9.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/9.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -21,3 +21,26 @@
     permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve";
 };
 
+grant codeBase "jrt:/jdk.incubator.httpclient" {
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
+
+    // ## why is SP not good enough. Check API @throws signatures and impl
+    permission java.net.SocketPermission "*","connect,resolve";
+    permission java.net.URLPermission "http:*","*:*";
+    permission java.net.URLPermission "https:*","*:*";
+    permission java.net.URLPermission "ws:*","*:*";
+    permission java.net.URLPermission "wss:*","*:*";
+    permission java.net.URLPermission "socket:*","CONNECT";  // proxy
+
+    // For request/response body processors, fromFile, asFile
+    permission java.io.FilePermission "<<ALL FILES>>","read,write";  // delete???
+
+    permission java.util.PropertyPermission "jdk.httpclient.*","read";
+
+    // ## these permissions do not appear in the NetPermission spec!!! JDK bug?
+    permission java.net.NetPermission "getSSLContext";
+    permission java.net.NetPermission "setSSLContext";
+};
+
--- a/jdk/test/java/net/httpclient/security/Driver.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/Driver.java	Tue Dec 13 02:04:23 2016 +0100
@@ -4,9 +4,7 @@
  *
  * This code is free software; you can redistribute 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.
+ * 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
@@ -27,7 +25,7 @@
  * @test
  * @bug 8087112
  * @library /lib/testlibrary/
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          java.logging
  *          jdk.httpserver
  * @build jdk.testlibrary.SimpleSSLContext jdk.testlibrary.Utils
@@ -62,6 +60,8 @@
  * Driver for tests
  */
 public class Driver {
+    // change the default value to "true" to get the subprocess traces.
+    final static boolean DEBUG = Boolean.parseBoolean(System.getProperty("test.debug", "false"));
 
     public static void main(String[] args) throws Throwable {
         System.out.println("Starting Driver");
@@ -79,12 +79,16 @@
         Logger(String cmdLine, Process p, String dir) throws IOException {
             super();
             setDaemon(true);
-            cmdLine = "Command line = [" + cmdLine + "]";
+            cmdLine = "Command line = [" + cmdLine + "]\n";
             stdout = p.getInputStream();
             File f = File.createTempFile("debug", ".txt", new File(dir));
             ps = new FileOutputStream(f);
             ps.write(cmdLine.getBytes());
             ps.flush();
+            if (DEBUG) {
+                System.out.print(cmdLine);
+                System.out.flush();
+            }
         }
 
         public void run() {
@@ -92,6 +96,10 @@
                 byte[] buf = new byte[128];
                 int c;
                 while ((c = stdout.read(buf)) != -1) {
+                    if (DEBUG) {
+                        System.out.write(buf, 0, c);
+                        System.out.flush();
+                    }
                     ps.write(buf, 0, c);
                     ps.flush();
                 }
@@ -122,6 +130,7 @@
             cmd.add("-Djava.security.policy=" + testSrc + sep + policy);
             cmd.add("-Dport.number=" + Integer.toString(Utils.getFreePort()));
             cmd.add("-Dport.number1=" + Integer.toString(Utils.getFreePort()));
+            cmd.add("-Djdk.httpclient.HttpClient.log=all,frames:all");
             cmd.add("-cp");
             cmd.add(testClassPath);
             cmd.add("Security");
--- a/jdk/test/java/net/httpclient/security/Security.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/security/Security.java	Tue Dec 13 02:04:23 2016 +0100
@@ -4,9 +4,7 @@
  *
  * This code is free software; you can redistribute 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.
+ * 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
@@ -26,7 +24,7 @@
 /*
  * @test
  * @bug 8087112
- * @modules java.httpclient
+ * @modules jdk.incubator.httpclient
  *          java.logging
  *          jdk.httpserver
  * @library /lib/testlibrary/
@@ -46,7 +44,7 @@
  * @run main/othervm/secure=java.lang.SecurityManager/policy=9.policy Security 9
  * @run main/othervm/secure=java.lang.SecurityManager/policy=0.policy Security 13
  * @run main/othervm/secure=java.lang.SecurityManager/policy=14.policy Security 14
- * @run main/othervm/secure=java.lang.SecurityManager/policy=15.policy Security 15
+ * @run main/othervm/secure=java.lang.SecurityManager/policy=15.policy -Djava.security.debug=access:domain,failure Security 15
  */
 
 // Tests 1, 10, 11 and 12 executed from Driver
@@ -68,10 +66,10 @@
 import java.net.URI;
 import java.net.URLClassLoader;
 import java.net.URL;
-import java.net.http.HttpHeaders;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
+import jdk.incubator.http.HttpHeaders;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.HttpRequest;
+import jdk.incubator.http.HttpResponse;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -81,14 +79,18 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
-import java.util.function.LongConsumer;
+import java.util.concurrent.Flow;
 import java.util.logging.ConsoleHandler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.lang.reflect.InvocationTargetException;
+import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
 /**
  * Security checks test
@@ -104,7 +106,7 @@
     static URI uri;
 
     interface Test {
-        public void execute() throws IOException, InterruptedException;
+        void execute() throws IOException, InterruptedException;
     }
 
     static class TestAndResult {
@@ -179,75 +181,71 @@
             // (0) policy does not have permission for file. Should fail
             test(false, () -> { // Policy 0
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (1) policy has permission for file URL
             test(true, () -> { //Policy 1
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (2) policy has permission for all file URLs under /files
             test(true, () -> { // Policy 2
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (3) policy has permission for first URL but not redirected URL
             test(false, () -> { // Policy 3
                 URI u = URI.create("http://127.0.0.1:" + port + "/redirect/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (4) policy has permission for both first URL and redirected URL
             test(true, () -> { // Policy 4
                 URI u = URI.create("http://127.0.0.1:" + port + "/redirect/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (5) policy has permission for redirected but not first URL
             test(false, () -> { // Policy 5
                 URI u = URI.create("http://127.0.0.1:" + port + "/redirect/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (6) policy has permission for file URL, but not method
             test(false, () -> { //Policy 6
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (7) policy has permission for file URL, method, but not header
             test(false, () -> { //Policy 7
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .header("X-Foo", "bar")
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u)
+                                                 .header("X-Foo", "bar")
+                                                 .GET()
+                                                 .build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (8) policy has permission for file URL, method and header
             test(true, () -> { //Policy 8
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .header("X-Foo", "bar")
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u)
+                                                 .header("X-Foo", "bar")
+                                                 .GET()
+                                                 .build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (9) policy has permission for file URL, method and header
             test(true, () -> { //Policy 9
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .headers("X-Foo", "bar", "X-Bar", "foo")
-                        .GET();
-                HttpResponse response = request.response();
+                HttpRequest request = HttpRequest.newBuilder(u)
+                                                 .headers("X-Foo", "bar", "X-Bar", "foo")
+                                                 .GET()
+                                                 .build();
+                HttpResponse<?> response = client.send(request, asString());
             }),
             // (10) policy has permission for destination URL but not for proxy
             test(false, () -> { //Policy 10
@@ -264,10 +262,9 @@
             // (13) async version of test 0
             test(false, () -> { // Policy 0
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 try {
-                    HttpResponse response = request.responseAsync().get();
+                    HttpResponse<?> response = client.sendAsync(request, asString()).get();
                 } catch (ExecutionException e) {
                     if (e.getCause() instanceof SecurityException) {
                         throw (SecurityException)e.getCause();
@@ -279,10 +276,9 @@
             // (14) async version of test 1
             test(true, () -> { //Policy 1
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 try {
-                    HttpResponse response = request.responseAsync().get();
+                    HttpResponse<?> response = client.sendAsync(request, asString()).get();
                 } catch (ExecutionException e) {
                     if (e.getCause() instanceof SecurityException) {
                         throw (SecurityException)e.getCause();
@@ -295,52 +291,62 @@
             //      thread does not gain ungranted privileges.
             test(false, () -> { //Policy 12
                 URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-                HttpRequest request = client.request(u)
-                        .GET();
-                HttpResponse response = request.response();
-                HttpResponse.BodyProcessor<String> stproc = HttpResponse.asString();
+                HttpRequest request = HttpRequest.newBuilder(u).GET().build();
+                HttpResponse.BodyHandler<String> sth = asString();
 
-                CompletableFuture<String> cf;
-                cf = response.bodyAsync(new HttpResponse.BodyProcessor<String>() {
-                        public void onResponseBodyChunk(ByteBuffer b) throws IOException {
-                            // do some mischief here
-                            SecurityManager sm = System.getSecurityManager();
-                            System.setSecurityManager(null);
-                            System.setSecurityManager(sm);
-                            // problem if we get this far
-                            stproc.onResponseBodyChunk(b);
-                        }
-                        public String onResponseBodyStart(long contentLength,
-                                        HttpHeaders responseHeaders,
-                                        LongConsumer fc) throws IOException {
-
-                            SecurityManager sm = System.getSecurityManager();
-                            // should succeed.
-                            sm.checkPermission(new RuntimePermission("foobar"));
-                            return stproc.onResponseBodyStart(contentLength,responseHeaders, fc);
-                        }
-                        public String onResponseComplete() throws IOException {
-                            return stproc.onResponseComplete();
-                        }
-                        public void onResponseError(Throwable t) {
-                            stproc.onResponseError(t);
+                CompletableFuture<HttpResponse<String>> cf =
+                    client.sendAsync(request, new HttpResponse.BodyHandler<String>() {
+                        @Override
+                        public HttpResponse.BodyProcessor<String> apply(int status, HttpHeaders responseHeaders)  {
+                            final HttpResponse.BodyProcessor<String> stproc = sth.apply(status, responseHeaders);
+                            return new HttpResponse.BodyProcessor<String>() {
+                                @Override
+                                public CompletionStage<String> getBody() {
+                                    return stproc.getBody();
+                                }
+                                @Override
+                                public void onNext(ByteBuffer item) {
+                                    SecurityManager sm = System.getSecurityManager();
+                                    // should succeed.
+                                    sm.checkPermission(new RuntimePermission("foobar"));
+                                    // do some mischief here
+                                    System.setSecurityManager(null);
+                                    System.setSecurityManager(sm);
+                                    // problem if we get this far
+                                    stproc.onNext(item);
+                                }
+                                @Override
+                                public void onSubscribe(Flow.Subscription subscription) {
+                                    stproc.onSubscribe(subscription);
+                                }
+                                @Override
+                                public void onError(Throwable throwable) {
+                                    stproc.onError(throwable);
+                                }
+                                @Override
+                                public void onComplete() {
+                                    stproc.onComplete();
+                                }
+                            };
                         }
                     }
                 );
                 try {
-                    System.out.println("Body = " + cf.get());// should not reach here
-                } catch (ExecutionException e) {
-                    if (e.getCause() instanceof SecurityException) {
-                        throw (SecurityException)e.getCause();
-                    } else {
-                        throw new RuntimeException(e);
-                    }
+                    cf.join();
+                } catch (CompletionException e) {
+                    Throwable t = e.getCause();
+                    if (t instanceof SecurityException)
+                        throw (SecurityException)t;
+                    else
+                        throw new RuntimeException(t);
                 }
             })
         };
     }
 
-    private static void directProxyTest(int proxyPort, boolean samePort) throws IOException, InterruptedException {
+    private static void directProxyTest(int proxyPort, boolean samePort)
+        throws IOException, InterruptedException
+    {
         Object proxy = null;
         try {
             proxy = getProxy(proxyPort, true);
@@ -354,17 +360,17 @@
         if (!samePort)
             proxyPort++;
 
-        HttpClient cl = HttpClient.create()
-                .proxy(ProxySelector.of(
-                                new InetSocketAddress("127.0.0.1", proxyPort)))
-                .build();
+        InetSocketAddress addr = new InetSocketAddress("127.0.0.1", proxyPort);
+        HttpClient cl = HttpClient.newBuilder()
+                                    .proxy(ProxySelector.of(addr))
+                                    .build();
         clients.add(cl);
 
         URI u = URI.create("http://127.0.0.1:" + port + "/files/foo.txt");
-        HttpRequest request = cl.request(u)
-                .headers("X-Foo", "bar", "X-Bar", "foo")
-                .GET();
-        HttpResponse response = request.response();
+        HttpRequest request = HttpRequest.newBuilder(u)
+                                         .headers("X-Foo", "bar", "X-Bar", "foo")
+                                         .build();
+        HttpResponse<?> response = cl.send(request, asString());
     }
 
     static void runtest(Test r, String policy, boolean succeeds) {
@@ -400,12 +406,10 @@
         int testnum = Integer.parseInt(args[0]);
         String policy = args[0];
 
-        client = HttpClient
-            .create()
-            .followRedirects(HttpClient.Redirect.ALWAYS)
-            .build();
+        client = HttpClient.newBuilder()
+                           .followRedirects(HttpClient.Redirect.ALWAYS)
+                           .build();
 
-        clients.add(HttpClient.getDefault());
         clients.add(client);
 
         try {
@@ -415,8 +419,12 @@
         } finally {
             s1.stop(0);
             executor.shutdownNow();
-            for (HttpClient client : clients)
-                client.executorService().shutdownNow();
+            for (HttpClient client : clients) {
+                Executor e = client.executor();
+                if (e instanceof ExecutorService) {
+                    ((ExecutorService)e).shutdownNow();
+                }
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/WSDriver.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8159053
+ * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.websocket:open
+ * @compile/module=jdk.incubator.httpclient jdk/incubator/http/internal/websocket/TestSupport.java
+ *
+ * @run testng/othervm --add-reads jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.HeaderWriterTest
+ * @run testng/othervm --add-reads jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.ReaderTest
+ * @run testng/othervm --add-reads jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.MaskerTest
+ * @run testng/othervm --add-reads jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.BuildingWebSocketTest
+ */
+public final class WSDriver {
+// * @run testng/othervm -XaddReads:jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.MockListenerTest
+// * @run testng/othervm -XaddReads:jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.MockChannelTest
+// * @run testng/othervm/timeout=1000 -Ddataproviderthreadcount=16 -XaddReads:jdk.incubator.httpclient=ALL-UNNAMED jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.PingTest
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/BuildingWebSocketTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import jdk.incubator.http.HttpClient;
+import jdk.incubator.http.WebSocket;
+import java.time.Duration;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static jdk.incubator.http.internal.websocket.TestSupport.assertCompletesExceptionally;
+import static jdk.incubator.http.internal.websocket.TestSupport.assertThrows;
+
+/*
+ * In some places in this class a new String is created out of a string literal.
+ * The idea is to make sure the code under test relies on something better than
+ * the reference equality ( == ) for string equality checks.
+ */
+public class BuildingWebSocketTest {
+
+    @Test
+    public void nulls() {
+        HttpClient c = HttpClient.newHttpClient();
+        URI uri = URI.create("ws://websocket.example.com");
+
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(null, listener()));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(null, null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .header(null, "value"));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .header("name", null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .header(null, null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .subprotocols(null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .subprotocols(null, "sub1"));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .subprotocols("sub1.example.com", (String) null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .subprotocols("sub1.example.com", (String[]) null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .subprotocols("sub1.example.com",
+                                          "sub2.example.com",
+                                          null));
+        assertThrows(NullPointerException.class,
+                     () -> c.newWebSocketBuilder(uri, listener())
+                            .connectTimeout(null));
+    }
+
+    @Test(dataProvider = "badURIs")
+    void illegalURI(String u) {
+        WebSocket.Builder b = HttpClient.newHttpClient()
+                .newWebSocketBuilder(URI.create(u), listener());
+        assertCompletesExceptionally(IllegalArgumentException.class, b.buildAsync());
+    }
+
+    @Test
+    public void illegalHeaders() {
+        List<String> headers = List.of("Authorization",
+                                       "Connection",
+                                       "Cookie",
+                                       "Content-Length",
+                                       "Date",
+                                       "Expect",
+                                       "From",
+                                       "Host",
+                                       "Origin",
+                                       "Proxy-Authorization",
+                                       "Referer",
+                                       "User-agent",
+                                       "Upgrade",
+                                       "Via",
+                                       "Warning",
+                                       "Sec-WebSocket-Accept",
+                                       "Sec-WebSocket-Extensions",
+                                       "Sec-WebSocket-Key",
+                                       "Sec-WebSocket-Protocol",
+                                       "Sec-WebSocket-Version").stream()
+                .map(String::new).collect(Collectors.toList());
+
+        Function<String, CompletionStage<?>> f =
+                header -> HttpClient
+                        .newHttpClient()
+                        .newWebSocketBuilder(URI.create("ws://websocket.example.com"),
+                                             listener())
+                        .buildAsync();
+
+        headers.forEach(h -> assertCompletesExceptionally(IllegalArgumentException.class, f.apply(h)));
+    }
+
+    // TODO: test for bad syntax headers
+    // TODO: test for overwrites (subprotocols) and additions (headers)
+
+    @Test(dataProvider = "badSubprotocols")
+    public void illegalSubprotocolsSyntax(String s) {
+        WebSocket.Builder b = HttpClient.newHttpClient()
+                .newWebSocketBuilder(URI.create("ws://websocket.example.com"),
+                                     listener());
+        b.subprotocols(s);
+        assertCompletesExceptionally(IllegalArgumentException.class, b.buildAsync());
+    }
+
+    @Test(dataProvider = "duplicatingSubprotocols")
+    public void illegalSubprotocolsDuplicates(String mostPreferred,
+                                              String[] lesserPreferred) {
+        WebSocket.Builder b = HttpClient.newHttpClient()
+                .newWebSocketBuilder(URI.create("ws://websocket.example.com"),
+                                     listener());
+        b.subprotocols(mostPreferred, lesserPreferred);
+        assertCompletesExceptionally(IllegalArgumentException.class, b.buildAsync());
+    }
+
+    @Test(dataProvider = "badConnectTimeouts")
+    public void illegalConnectTimeout(Duration d) {
+        WebSocket.Builder b = HttpClient.newHttpClient()
+                .newWebSocketBuilder(URI.create("ws://websocket.example.com"),
+                                     listener());
+        b.connectTimeout(d);
+        assertCompletesExceptionally(IllegalArgumentException.class, b.buildAsync());
+    }
+
+    @DataProvider
+    public Object[][] badURIs() {
+        return new Object[][]{
+                {"http://example.com"},
+                {"ftp://example.com"},
+                {"wss://websocket.example.com/hello#fragment"},
+                {"ws://websocket.example.com/hello#fragment"},
+        };
+    }
+
+    @DataProvider
+    public Object[][] badConnectTimeouts() {
+        return new Object[][]{
+                {Duration.ofDays   ( 0)},
+                {Duration.ofDays   (-1)},
+                {Duration.ofHours  ( 0)},
+                {Duration.ofHours  (-1)},
+                {Duration.ofMinutes( 0)},
+                {Duration.ofMinutes(-1)},
+                {Duration.ofSeconds( 0)},
+                {Duration.ofSeconds(-1)},
+                {Duration.ofMillis ( 0)},
+                {Duration.ofMillis (-1)},
+                {Duration.ofNanos  ( 0)},
+                {Duration.ofNanos  (-1)},
+                {Duration.ZERO},
+        };
+    }
+
+    // https://tools.ietf.org/html/rfc7230#section-3.2.6
+    // https://tools.ietf.org/html/rfc20
+    @DataProvider
+    public static Object[][] badSubprotocols() {
+        return new Object[][]{
+                {new String("")},
+                {"round-brackets("},
+                {"round-brackets)"},
+                {"comma,"},
+                {"slash/"},
+                {"colon:"},
+                {"semicolon;"},
+                {"angle-brackets<"},
+                {"angle-brackets>"},
+                {"equals="},
+                {"question-mark?"},
+                {"at@"},
+                {"brackets["},
+                {"backslash\\"},
+                {"brackets]"},
+                {"curly-brackets{"},
+                {"curly-brackets}"},
+                {"space "},
+                {"non-printable-character " + Character.toString((char) 31)},
+                {"non-printable-character " + Character.toString((char) 127)},
+        };
+    }
+
+    @DataProvider
+    public static Object[][] duplicatingSubprotocols() {
+        return new Object[][]{
+                {"a.b.c", new String[]{"a.b.c"}},
+                {"a.b.c", new String[]{"x.y.z", "p.q.r", "x.y.z"}},
+                {"a.b.c", new String[]{new String("a.b.c")}},
+        };
+    }
+
+    private static WebSocket.Listener listener() {
+        return new WebSocket.Listener() { };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/CloseTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jdk.incubator.http.WebSocket;
+
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+
+import static jdk.incubator.http.internal.websocket.TestSupport.Expectation.ifExpect;
+import static jdk.incubator.http.internal.websocket.TestSupport.cartesianIterator;
+import static java.util.Arrays.asList;
+import static java.util.List.of;
+
+/*
+ * Tests for Close message handling: examines sendClose/onClose contracts.
+ */
+public final class CloseTest {
+
+    /*
+     * Verifies the domain of the arguments of sendClose(code, reason).
+     */
+    @Test(dataProvider = "sendClose")
+    public void testSendCloseArguments(int code, String reason) {
+        WebSocket ws = newWebSocket();
+        ifExpect(
+                reason == null,
+                NullPointerException.class::isInstance)
+        .orExpect(
+                !isOutgoingCodeLegal(code),
+                IllegalArgumentException.class::isInstance)
+        .orExpect(
+                !isReasonLegal(reason),
+                IllegalArgumentException.class::isInstance)
+        .assertThrows(() -> ws.sendClose(code, reason));
+    }
+
+    /*
+     * After sendClose(code, reason) has returned normally or exceptionally, no
+     * more messages can be sent. However, if the invocation has thrown IAE/NPE
+     * (i.e. programming error) messages can still be sent (failure atomicity).
+     */
+    public void testSendClose(int code, String reason) {
+        newWebSocket().sendClose(10, "");
+    }
+
+    /*
+     * After sendClose() has been invoked, no more messages can be sent.
+     */
+    public void testSendClose() {
+        WebSocket ws = newWebSocket();
+        CompletableFuture<WebSocket> cf = ws.sendClose();
+    }
+
+    // TODO: sendClose can be invoked whenever is suitable without ISE
+    // + idempotency
+
+    /*
+     * An invocation of sendClose(code, reason) will cause a Close message with
+     * the same code and the reason to appear on the wire.
+     */
+    public void testSendCloseWysiwyg(int code, String reason) {
+
+    }
+
+    /*
+     * An invocation of sendClose() will cause an empty Close message to appear
+     * on the wire.
+     */
+    public void testSendCloseWysiwyg() {
+
+    }
+
+    /*
+     * Automatic Closing handshake. Listener receives onClose() and returns from
+     * it. WebSocket closes in accordance to the returned value.
+     */
+    public void testClosingHandshake1() {
+        // TODO: closed if observed shortly after the returned CS completes
+    }
+
+    /*
+     * sendClose is invoked from within onClose. After sendClose has returned,
+     * isClosed() reports true.
+     */
+    public void testClosingHandshake2() {
+        // 1. newWebSocket().sendClose();
+        // 2. onClose return null
+        // 3. isClosed() == true
+    }
+
+    /*
+     * sendClose has been invoked, then onClose. Shortly after onClose has
+     * returned, isClosed reports true.
+     */
+    public void testClosingHandshake3() {
+    }
+
+    /*
+     * Return from onClose with nevercompleting CS then sendClose().
+     */
+    public void testClosingHandshake4() {
+
+    }
+
+    /*
+     * Exceptions thrown from onClose and exceptions a CS returned from onClose
+     * "completes exceptionally" with are ignored. In other words, they are
+     * never reported to onError().
+     */
+    public void testOnCloseExceptions() {
+
+    }
+
+    /*
+     * An incoming Close message on the wire will cause an invocation of onClose
+     * with appropriate values. However, if this message violates the WebSocket
+     * Protocol, onError is invoked instead.
+     *
+     * // TODO: automatic close (if error) AND isClose returns true from onError
+     */
+    public void testOnCloseWysiwyg() {
+
+    }
+
+    /*
+     * Data is read off the wire. An end-of-stream has been reached while
+     * reading a frame.
+     *
+     * onError is invoked with java.net.ProtocolException and the WebSocket this
+     * listener has been attached to
+     */
+    public void testUnexpectedEOS() {
+
+    }
+
+    /*
+     * Data is read off the wire. An end-of-stream has been reached in between
+     * frames, and no Close frame has been received yet.
+     *
+     * onClose is invoked with the status code 1006 and the WebSocket this
+     * listener has been attached to
+     */
+    public void testEOS() {
+
+    }
+
+    // TODO: check buffers for change
+
+    @DataProvider(name = "sendClose")
+    public Iterator<Object[]> createData() {
+        List<Integer> codes = asList(
+                Integer.MIN_VALUE, -1, 0, 1, 500, 998, 999, 1000, 1001, 1002,
+                1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012,
+                1013, 1014, 1015, 1016, 2998, 2999, 3000, 3001, 3998, 3999,
+                4000, 4001, 4998, 4999, 5000, 5001, 32768, 65535, 65536,
+                Integer.MAX_VALUE);
+        String longReason1 = "This is a reason string. Nothing special except " +
+                "its UTF-8 representation is a bit " +
+                "longer than one hundred and twenty three bytes.";
+        assert longReason1.getBytes(StandardCharsets.UTF_8).length > 123;
+
+        // Russian alphabet repeated cyclically until it's enough to pass "123"
+        // bytes length
+        StringBuilder b = new StringBuilder();
+        char c = '\u0410';
+        for (int i = 0; i < 62; i++) {
+            b.append(c);
+            if (++c > '\u042F') {
+                c = '\u0410';
+            }
+        }
+        String longReason2 = b.toString();
+        assert longReason2.length() <= 123
+                && longReason2.getBytes(StandardCharsets.UTF_8).length > 123;
+
+        String malformedReason = new String(new char[]{0xDC00, 0xD800});
+
+        List<String> reasons = asList
+                (null, "", "abc", longReason1, longReason2, malformedReason);
+
+        return cartesianIterator(of(codes, reasons), args -> args);
+    }
+
+    private boolean isReasonLegal(String reason) {
+        if (reason == null) {
+            return false;
+        }
+        ByteBuffer result;
+        try {
+            result = StandardCharsets.UTF_8.newEncoder().encode(CharBuffer.wrap(reason));
+        } catch (CharacterCodingException e) {
+            return false;
+        }
+        return result.remaining() <= 123;
+    }
+
+    private static boolean isOutgoingCodeLegal(int code) {
+        if (code < 1000 || code > 4999) {
+            return false;
+        }
+        if (code < 1016) {
+            return code == 1000 || code == 1001 || code == 1008 || code == 1011;
+        }
+        return code >= 3000;
+    }
+
+    private WebSocket newWebSocket() {
+        WebSocket.Listener l = new WebSocket.Listener() { };
+        return new WebSocketImpl(URI.create("ws://example.com"),
+                                 "",
+                                 new MockChannel.Builder().build(),
+                                 l);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/DataProviders.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.DataProvider;
+
+import jdk.incubator.http.internal.websocket.TestSupport.F5;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
+
+import static jdk.incubator.http.internal.websocket.TestSupport.cartesianIterator;
+import static jdk.incubator.http.internal.websocket.TestSupport.concat;
+import static jdk.incubator.http.internal.websocket.TestSupport.iteratorOf;
+import static jdk.incubator.http.internal.websocket.TestSupport.iteratorOf1;
+import static java.util.List.of;
+
+/*
+ * Data providers for WebSocket tests
+ */
+public final class DataProviders {
+
+    /*
+     * Various ByteBuffer-s to be passed to sendPing/sendPong.
+     *
+     * Actual data is put in the middle of the buffer to make sure the code under
+     * test relies on position/limit rather than on 0 and capacity.
+     *
+     *     +-------------------+-------~ ~-------------+--------------+
+     *     |<---- leading ---->|<------~ ~--- data --->|<- trailing ->|
+     *     +-------------------+-------~ ~-------------+--------------+
+     *     ^0                   ^position               ^limit         ^capacity
+     */
+    @DataProvider(name = "outgoingData", parallel = true)
+    public static Iterator<Object[]> outgoingData() {
+        List<Integer> leading  = of(0, 1, 17, 125);
+        List<Integer> trailing = of(0, 1, 19, 123);
+        List<Integer> sizes    = of(0, 1, 2, 17, 32, 64, 122, 123, 124, 125, 126, 127, 128, 256);
+        List<Boolean> direct   = of(true, false);
+        List<Boolean> readonly = of(false); // TODO: return readonly (true)
+        F5<Integer, Integer, Integer, Boolean, Boolean, Object[]> f =
+                (l, t, s, d, r) -> {
+                    ByteBuffer b;
+                    if (d) {
+                        b = ByteBuffer.allocateDirect(l + t + s);
+                    } else {
+                        b = ByteBuffer.allocate(l + t + s);
+                    }
+                    fill(b);
+                    if (r) {
+                        b = b.asReadOnlyBuffer();
+                    }
+                    b.position(l).limit(l + s);
+                    return new ByteBuffer[]{b};
+                };
+        Iterator<Object[]> product = cartesianIterator(leading, trailing, sizes, direct, readonly, f);
+        Iterator<Object[]> i = iteratorOf1(new Object[]{null});
+        return concat(iteratorOf(i, product));
+    }
+
+    @DataProvider(name = "incomingData", parallel = true)
+    public static Iterator<Object[]> incomingData() {
+        return Stream.of(0, 1, 2, 17, 63, 125)
+                .map(i -> new Object[]{fill(ByteBuffer.allocate(i))})
+                .iterator();
+    }
+
+    @DataProvider(name = "incorrectFrame")
+    public static Iterator<Object[]> incorrectFrame() {
+        List<Boolean> fin   = of(true, false );
+        List<Boolean> rsv1  = of(true, false );
+        List<Boolean> rsv2  = of(true, false );
+        List<Boolean> rsv3  = of(true, false );
+        List<Integer> sizes = of(0, 126, 1024);
+        return cartesianIterator(fin, rsv1, rsv2, rsv3, sizes,
+                (a, b, c, d, e) -> new Object[]{a, b, c, d, ByteBuffer.allocate(e)});
+    }
+
+    private static ByteBuffer fill(ByteBuffer b) {
+        int i = 0;
+        while (b.hasRemaining()) {
+            b.put((byte) (++i & 0xff));
+        }
+        return b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/HeaderWriterTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.websocket.Frame.HeaderWriter;
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+
+import java.nio.ByteBuffer;
+import java.util.OptionalInt;
+
+import static java.util.OptionalInt.empty;
+import static java.util.OptionalInt.of;
+import static org.testng.Assert.assertEquals;
+import static jdk.incubator.http.internal.websocket.TestSupport.assertThrows;
+import static jdk.incubator.http.internal.websocket.TestSupport.forEachPermutation;
+
+public class HeaderWriterTest {
+
+    private long cases, frames;
+
+    @Test
+    public void negativePayload() {
+        System.out.println("testing negative payload");
+        HeaderWriter w = new HeaderWriter();
+        assertThrows(IllegalArgumentException.class,
+                ".*(?i)negative.*",
+                () -> w.payloadLen(-1));
+    }
+
+    @Test
+    public void test() {
+        System.out.println("testing regular payloads");
+        final long[] payloads = {0, 126, 65536, Integer.MAX_VALUE + 1L};
+        final OptionalInt[] masks = {empty(), of(-1), of(0), of(0xCAFEBABE),
+                of(Integer.MAX_VALUE), of(Integer.MIN_VALUE)};
+        for (boolean fin : new boolean[]{true, false}) {
+            for (boolean rsv1 : new boolean[]{true, false}) {
+                for (boolean rsv2 : new boolean[]{true, false}) {
+                    for (boolean rsv3 : new boolean[]{true, false}) {
+                        for (Opcode opcode : Opcode.values()) {
+                            for (long payloadLen : payloads) {
+                                for (OptionalInt mask : masks) {
+                                    verify(fin, rsv1, rsv2, rsv3, opcode, payloadLen, mask);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        System.out.println("Frames: " + frames + ", Total cases: " + cases);
+    }
+
+    private void verify(boolean fin,
+                        boolean rsv1,
+                        boolean rsv2,
+                        boolean rsv3,
+                        Opcode opcode,
+                        long payloadLen,
+                        OptionalInt mask) {
+        frames++;
+        HeaderWriter writer = new HeaderWriter();
+        ByteBuffer expected = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES);
+        writer.fin(fin).rsv1(rsv1).rsv2(rsv2).rsv3(rsv3).opcode(opcode).payloadLen(payloadLen);
+        mask.ifPresentOrElse(writer::mask, writer::noMask);
+        writer.write(expected);
+        expected.flip();
+        verifyPermutations(expected, writer,
+                () -> writer.fin(fin),
+                () -> writer.rsv1(rsv1),
+                () -> writer.rsv2(rsv2),
+                () -> writer.rsv3(rsv3),
+                () -> writer.opcode(opcode),
+                () -> writer.payloadLen(payloadLen),
+                () -> mask.ifPresentOrElse(writer::mask, writer::noMask));
+    }
+
+    private void verifyPermutations(ByteBuffer expected,
+                                    HeaderWriter writer,
+                                    Runnable... actions) {
+        forEachPermutation(actions.length,
+                order -> {
+                    cases++;
+                    for (int i : order) {
+                        actions[i].run();
+                    }
+                    ByteBuffer actual = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES + 2);
+                    writer.write(actual);
+                    actual.flip();
+                    assertEquals(actual, expected);
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MaskerTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.security.SecureRandom;
+import java.util.stream.IntStream;
+
+import static org.testng.Assert.assertEquals;
+import static jdk.incubator.http.internal.websocket.Frame.Masker.transferMasking;
+import static jdk.incubator.http.internal.websocket.TestSupport.forEachBufferPartition;
+import static jdk.incubator.http.internal.websocket.TestSupport.fullCopy;
+
+public class MaskerTest {
+
+    private static final SecureRandom random = new SecureRandom();
+
+    @Test
+    public void stateless() {
+        IntStream.iterate(0, i -> i + 1).limit(125).boxed()
+                .forEach(r -> {
+                    int m = random.nextInt();
+                    ByteBuffer src = createSourceBuffer(r);
+                    ByteBuffer dst = createDestinationBuffer(r);
+                    verify(src, dst, maskArray(m), 0,
+                            () -> transferMasking(src, dst, m));
+                });
+    }
+
+    /*
+     * Stateful masker to make sure setting a mask resets the state as if a new
+     * Masker instance is created each time
+     */
+    private final Frame.Masker masker = new Frame.Masker();
+
+    @Test
+    public void stateful0() {
+        // This size (17 = 8 + 8 + 1) should test all the stages
+        // (galloping/slow) of masking good enough
+        int N = 17;
+        ByteBuffer src = createSourceBuffer(N);
+        ByteBuffer dst = createDestinationBuffer(N);
+        int mask = random.nextInt();
+        forEachBufferPartition(src,
+                buffers -> {
+                    int offset = 0;
+                    masker.mask(mask);
+                    int[] maskBytes = maskArray(mask);
+                    for (ByteBuffer s : buffers) {
+                        offset = verify(s, dst, maskBytes, offset,
+                                () -> masker.transferMasking(s, dst));
+                    }
+                });
+    }
+
+    @Test
+    public void stateful1() {
+        int m = random.nextInt();
+        masker.mask(m);
+        ByteBuffer src = ByteBuffer.allocate(0);
+        ByteBuffer dst = ByteBuffer.allocate(16);
+        verify(src, dst, maskArray(m), 0,
+                () -> masker.transferMasking(src, dst));
+    }
+
+    private static int verify(ByteBuffer src,
+                              ByteBuffer dst,
+                              int[] maskBytes,
+                              int offset,
+                              Runnable masking) {
+        ByteBuffer srcCopy = fullCopy(src);
+        ByteBuffer dstCopy = fullCopy(dst);
+        masking.run();
+        int srcRemaining = srcCopy.remaining();
+        int dstRemaining = dstCopy.remaining();
+        int masked = Math.min(srcRemaining, dstRemaining);
+        // 1. position check
+        assertEquals(src.position(), srcCopy.position() + masked);
+        assertEquals(dst.position(), dstCopy.position() + masked);
+        // 2. masking check
+        src.position(srcCopy.position());
+        dst.position(dstCopy.position());
+        for (; src.hasRemaining() && dst.hasRemaining();
+             offset = (offset + 1) & 3) {
+            assertEquals(dst.get(), src.get() ^ maskBytes[offset]);
+        }
+        // 3. corruption check
+        // 3.1 src contents haven't changed
+        int srcPosition = src.position();
+        int srcLimit = src.limit();
+        src.clear();
+        srcCopy.clear();
+        assertEquals(src, srcCopy);
+        src.limit(srcLimit).position(srcPosition); // restore src
+        // 3.2 dst leading and trailing regions' contents haven't changed
+        int dstPosition = dst.position();
+        int dstInitialPosition = dstCopy.position();
+        int dstLimit = dst.limit();
+        // leading
+        dst.position(0).limit(dstInitialPosition);
+        dstCopy.position(0).limit(dstInitialPosition);
+        assertEquals(dst, dstCopy);
+        // trailing
+        dst.limit(dst.capacity()).position(dstLimit);
+        dstCopy.limit(dst.capacity()).position(dstLimit);
+        assertEquals(dst, dstCopy);
+        // restore dst
+        dst.position(dstPosition).limit(dstLimit);
+        return offset;
+    }
+
+    private static ByteBuffer createSourceBuffer(int remaining) {
+        int leading = random.nextInt(4);
+        int trailing = random.nextInt(4);
+        byte[] bytes = new byte[leading + remaining + trailing];
+        random.nextBytes(bytes);
+        return ByteBuffer.wrap(bytes).position(leading).limit(leading + remaining);
+    }
+
+    private static ByteBuffer createDestinationBuffer(int remaining) {
+        int leading = random.nextInt(4);
+        int trailing = random.nextInt(4);
+        return ByteBuffer.allocate(leading + remaining + trailing)
+                .position(leading).limit(leading + remaining);
+    }
+
+    private static int[] maskArray(int mask) {
+        return new int[]{
+                (byte) (mask >>> 24),
+                (byte) (mask >>> 16),
+                (byte) (mask >>>  8),
+                (byte) (mask >>>  0)
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockChannel.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.WebSocket.MessagePart;
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+import jdk.incubator.http.internal.websocket.TestSupport.F1;
+import jdk.incubator.http.internal.websocket.TestSupport.F2;
+import jdk.incubator.http.internal.websocket.TestSupport.InvocationChecker;
+import jdk.incubator.http.internal.websocket.TestSupport.InvocationExpectation;
+import jdk.incubator.http.internal.websocket.TestSupport.Mock;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectionKey;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.OptionalInt;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Supplier;
+
+import static jdk.incubator.http.internal.websocket.Frame.MAX_HEADER_SIZE_BYTES;
+
+final class MockChannel implements RawChannel, Mock {
+
+    /* Reads and writes must be able to be served concurrently, thus 2 threads */ // TODO: test this
+    private final Executor executor = Executors.newFixedThreadPool(2);
+    private final Object stateLock = new Object();
+    private final Object readLock = new Object();
+    private final Object writeLock = new Object();
+    private volatile boolean closed;
+    private boolean isInputOpen = true;
+    private boolean isOutputOpen = true;
+    private final Frame.Reader reader = new Frame.Reader();
+    private final MockFrameConsumer delegate;
+    private final Iterator<ReadRule> readScenario;
+    private ReadRule currentRule;
+    private final AtomicBoolean handedOver = new AtomicBoolean();
+
+    private MockChannel(Iterable<ReadRule> scenario,
+                        Iterable<InvocationExpectation> expectations) {
+        Iterator<ReadRule> iterator = scenario.iterator();
+        if (!iterator.hasNext()) {
+            throw new RuntimeException();
+        }
+        this.readScenario = iterator;
+        this.currentRule = iterator.next();
+        this.delegate = new MockFrameConsumer(expectations);
+    }
+
+    @Override
+    public void registerEvent(RawEvent event) throws IOException {
+        int ops = event.interestOps();
+        if ((ops & SelectionKey.OP_WRITE) != 0) {
+            synchronized (stateLock) {
+                checkOpen();
+                executor.execute(event::handle);
+            }
+        } else if ((ops & SelectionKey.OP_READ) != 0) {
+            CompletionStage<?> cs;
+            synchronized (readLock) {
+                cs = currentRule().whenReady();
+                synchronized (stateLock) {
+                    checkOpen();
+                    cs.thenRun(() -> executor.execute(event::handle));
+                }
+            }
+        } else {
+            throw new RuntimeException("Unexpected registration: " + ops);
+        }
+    }
+
+    @Override
+    public ByteBuffer initialByteBuffer() throws IllegalStateException {
+        if (!handedOver.compareAndSet(false, true)) {
+            throw new IllegalStateException();
+        }
+        return ByteBuffer.allocate(0);
+    }
+
+    @Override
+    public ByteBuffer read() throws IOException {
+        synchronized (readLock) {
+            checkOpen();
+            synchronized (stateLock) {
+                if (!isInputOpen) {
+                    return null;
+                }
+            }
+            ByteBuffer r = currentRule().read();
+            checkOpen();
+            return r;
+        }
+    }
+
+    @Override
+    public long write(ByteBuffer[] src, int offset, int len) throws IOException {
+        synchronized (writeLock) {
+            checkOpen();
+            synchronized (stateLock) {
+                if (!isOutputOpen) {
+                    throw new ClosedChannelException();
+                }
+            }
+            long n = 0;
+            for (int i = offset; i < offset + len && isOpen(); i++) {
+                ByteBuffer b = src[i];
+                int rem = src[i].remaining();
+                while (b.hasRemaining() && isOpen()) {
+                    reader.readFrame(b, delegate);
+                }
+                n += rem;
+            }
+            checkOpen();
+            return n;
+        }
+    }
+
+    public boolean isOpen() {
+        return !closed;
+    }
+
+    @Override
+    public void shutdownInput() throws IOException {
+        synchronized (stateLock) {
+            if (!isOpen()) {
+                throw new ClosedChannelException();
+            }
+            isInputOpen = false;
+        }
+    }
+
+    @Override
+    public void shutdownOutput() throws IOException {
+        synchronized (stateLock) {
+            if (!isOpen()) {
+                throw new ClosedChannelException();
+            }
+            isOutputOpen = false;
+        }
+    }
+
+    @Override
+    public void close() {
+        synchronized (stateLock) {
+            closed = true;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[" + (closed ? "closed" : "open") + "]";
+    }
+
+    private ReadRule currentRule() {
+        assert Thread.holdsLock(readLock);
+        while (!currentRule.applies()) { // There should be the terminal rule which always applies
+            currentRule = readScenario.next();
+        }
+        return currentRule;
+    }
+
+    private void checkOpen() throws ClosedChannelException {
+        if (!isOpen()) {
+            throw new ClosedChannelException();
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> expectations(long timeout, TimeUnit unit) {
+        return delegate.expectations(timeout, unit);
+    }
+
+    private static class MockFrameConsumer extends FrameConsumer implements Mock {
+
+        private final Frame.Masker masker = new Frame.Masker();
+
+        MockFrameConsumer(Iterable<InvocationExpectation> expectations) {
+            super(new MockMessageStreamConsumer(expectations));
+        }
+
+        @Override
+        public void mask(boolean value) {
+        }
+
+        @Override
+        public void maskingKey(int value) {
+            masker.mask(value);
+        }
+
+        @Override
+        public void payloadData(ByteBuffer data) {
+            int p = data.position();
+            int l = data.limit();
+            masker.transferMasking(data, data);
+//            select(p, l, data); FIXME
+            super.payloadData(data);
+        }
+
+        @Override
+        public CompletableFuture<Void> expectations(long timeout, TimeUnit unit) {
+            return ((Mock) getOutput()).expectations(timeout, unit);
+        }
+    }
+
+    private static final class MockMessageStreamConsumer implements MessageStreamConsumer, Mock {
+
+        private final InvocationChecker checker;
+
+        MockMessageStreamConsumer(Iterable<InvocationExpectation> expectations) {
+            checker = new InvocationChecker(expectations);
+        }
+
+        @Override
+        public void onText(MessagePart part, CharSequence data) {
+            checker.checkInvocation("onText", part, data);
+        }
+
+        @Override
+        public void onBinary(MessagePart part, ByteBuffer data) {
+            checker.checkInvocation("onBinary", part, data);
+        }
+
+        @Override
+        public void onPing(ByteBuffer data) {
+            checker.checkInvocation("onPing", data);
+        }
+
+        @Override
+        public void onPong(ByteBuffer data) {
+            checker.checkInvocation("onPong", data);
+        }
+
+        @Override
+        public void onClose(OptionalInt statusCode, CharSequence reason) {
+            checker.checkInvocation("onClose", statusCode, reason);
+        }
+
+        @Override
+        public void onError(Exception e) {
+            checker.checkInvocation("onError", e);
+        }
+
+        @Override
+        public void onComplete() {
+            checker.checkInvocation("onComplete");
+        }
+
+        @Override
+        public CompletableFuture<Void> expectations(long timeout, TimeUnit unit) {
+            return checker.expectations(timeout, unit);
+        }
+    }
+
+    public static final class Builder {
+
+        private final Frame.HeaderWriter b = new Frame.HeaderWriter();
+        private final List<InvocationExpectation> expectations = new LinkedList<>();
+        private final List<ReadRule> scenario = new LinkedList<>();
+
+        Builder expectPing(F1<? super ByteBuffer, Boolean> predicate) {
+            InvocationExpectation e = new InvocationExpectation("onPing",
+                    args -> predicate.apply((ByteBuffer) args[0]));
+            expectations.add(e);
+            return this;
+        }
+
+        Builder expectPong(F1<? super ByteBuffer, Boolean> predicate) {
+            InvocationExpectation e = new InvocationExpectation("onPong",
+                    args -> predicate.apply((ByteBuffer) args[0]));
+            expectations.add(e);
+            return this;
+        }
+
+        Builder expectClose(F2<? super Integer, ? super String, Boolean> predicate) {
+            InvocationExpectation e = new InvocationExpectation("onClose",
+                    args -> predicate.apply((Integer) args[0], (String) args[1]));
+            expectations.add(e);
+            return this;
+        }
+
+        Builder provideFrame(boolean fin, boolean rsv1, boolean rsv2,
+                             boolean rsv3, Opcode opcode, ByteBuffer data) {
+
+            ByteBuffer b = ByteBuffer.allocate(MAX_HEADER_SIZE_BYTES + data.remaining());
+            this.b.fin(fin).rsv1(rsv1).rsv2(rsv2).rsv3(rsv3).opcode(opcode).noMask()
+                    .payloadLen(data.remaining()).write(b);
+
+            int p = data.position();
+            int l = data.limit();
+            b.put(data);
+            b.flip();
+//            select(p, l, data); FIXME
+
+            ReadRule r = new ReadRule() {
+
+                private volatile boolean provided;
+
+                @Override
+                public CompletionStage<?> whenReady() {
+                    return NOW;
+                }
+
+                @Override
+                public ByteBuffer read() throws IOException {
+                    provided = true;
+                    return data;
+                }
+
+                @Override
+                public boolean applies() {
+                    return !provided;
+                }
+            };
+            scenario.add(r);
+            return this;
+        }
+
+        Builder provideEos() {
+            ReadRule r = new ReadRule() {
+
+                @Override
+                public CompletionStage<?> whenReady() {
+                    return NOW;
+                }
+
+                @Override
+                public ByteBuffer read() throws IOException {
+                    return null;
+                }
+
+                @Override
+                public boolean applies() {
+                    return true;
+                }
+            };
+            scenario.add(r);
+            return this;
+        }
+
+        Builder provideException(Supplier<? extends IOException> s) {
+            return this;
+        }
+
+        MockChannel build() {
+            LinkedList<ReadRule> scenario = new LinkedList<>(this.scenario);
+            scenario.add(new Terminator());
+            return new MockChannel(scenario, new LinkedList<>(expectations));
+        }
+    }
+
+    private interface ReadRule {
+
+        /*
+         * Returns a CS which when completed means `read(ByteBuffer dst)` can be
+         * invoked
+         */
+        CompletionStage<?> whenReady();
+
+        ByteBuffer read() throws IOException;
+
+        /*
+         * Returns true if this rule still applies, otherwise returns false
+         */
+        boolean applies();
+    }
+
+    public static final class Terminator implements ReadRule {
+
+        @Override
+        public CompletionStage<?> whenReady() {
+            return NEVER;
+        }
+
+        @Override
+        public ByteBuffer read() {
+            return ByteBuffer.allocate(0);
+        }
+
+        @Override
+        public boolean applies() {
+            return true;
+        }
+    }
+
+    private static final CompletionStage<?> NOW = CompletableFuture.completedStage(null);
+    private static final CompletionStage<?> NEVER = new CompletableFuture();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockChannelTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+
+import java.io.IOException;
+import jdk.incubator.http.internal.websocket.TestSupport.AssertionFailedException;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+
+import static jdk.incubator.http.internal.websocket.TestSupport.assertThrows;
+import static jdk.incubator.http.internal.websocket.TestSupport.checkExpectations;
+import static jdk.incubator.http.internal.websocket.Frame.MAX_HEADER_SIZE_BYTES;
+
+public final class MockChannelTest {
+
+    // TODO: tests for read (stubbing)
+
+    @Test
+    public void testPass01() {
+        MockChannel ch = new MockChannel.Builder().build();
+        checkExpectations(1, TimeUnit.SECONDS, ch);
+    }
+
+    @Test
+    public void testPass02() throws IOException {
+        int len = 8;
+        ByteBuffer header = ByteBuffer.allocate(MAX_HEADER_SIZE_BYTES);
+        ByteBuffer data = ByteBuffer.allocate(len);
+        new Frame.HeaderWriter()
+                .fin(true).opcode(Opcode.PONG).payloadLen(len).mask(0x12345678)
+                .write(header);
+        header.flip();
+        MockChannel ch = new MockChannel.Builder()
+                .expectPong(bb -> bb.remaining() == len)
+                .build();
+        ch.write(new ByteBuffer[]{header, data}, 0, 2);
+        checkExpectations(1, TimeUnit.SECONDS, ch);
+    }
+
+    @Test
+    public void testPass03() throws IOException {
+        int len = 8;
+        ByteBuffer header = ByteBuffer.allocate(MAX_HEADER_SIZE_BYTES);
+        ByteBuffer data = ByteBuffer.allocate(len - 2); // not all data is written
+        new Frame.HeaderWriter()
+                .fin(true).opcode(Opcode.PONG).payloadLen(len).mask(0x12345678)
+                .write(header);
+        header.flip();
+        MockChannel ch = new MockChannel.Builder().build(); // expected no invocations
+        ch.write(new ByteBuffer[]{header, data}, 0, 2);
+        checkExpectations(1, TimeUnit.SECONDS, ch);
+    }
+
+    @Test
+    public void testFail01() {
+        MockChannel ch = new MockChannel.Builder()
+                .expectClose((code, reason) -> code == 1002 && reason.isEmpty())
+                .build();
+        assertThrows(AssertionFailedException.class,
+                () -> checkExpectations(1, TimeUnit.SECONDS, ch));
+    }
+
+    @Test
+    public void testFail02() throws IOException {
+        ByteBuffer header = ByteBuffer.allocate(MAX_HEADER_SIZE_BYTES);
+        new Frame.HeaderWriter()
+                .fin(true).opcode(Opcode.CLOSE).payloadLen(2).mask(0x12345678)
+                .write(header);
+        header.flip();
+        ByteBuffer data = ByteBuffer.allocate(2).putChar((char) 1004).flip();
+        MockChannel ch = new MockChannel.Builder()
+                .expectClose((code, reason) -> code == 1002 && reason.isEmpty())
+                .build();
+        ch.write(new ByteBuffer[]{header, data}, 0, 2);
+        assertThrows(AssertionFailedException.class,
+                () -> checkExpectations(1, TimeUnit.SECONDS, ch));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockListener.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import jdk.incubator.http.internal.websocket.TestSupport.F1;
+import jdk.incubator.http.internal.websocket.TestSupport.F2;
+import jdk.incubator.http.internal.websocket.TestSupport.F3;
+import jdk.incubator.http.internal.websocket.TestSupport.InvocationChecker;
+import jdk.incubator.http.internal.websocket.TestSupport.InvocationExpectation;
+import jdk.incubator.http.internal.websocket.TestSupport.Mock;
+import jdk.incubator.http.WebSocket;
+import jdk.incubator.http.WebSocket.Listener;
+import jdk.incubator.http.WebSocket.MessagePart;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.TimeUnit;
+
+final class MockListener implements Listener, Mock {
+
+    private final InvocationChecker checker;
+
+    @Override
+    public CompletableFuture<Void> expectations(long timeout, TimeUnit unit) {
+        return checker.expectations(timeout, unit);
+    }
+
+    public static final class Builder {
+
+        private final List<InvocationExpectation> expectations = new LinkedList<>();
+
+        Builder expectOnOpen(F1<? super WebSocket, Boolean> predicate) {
+            InvocationExpectation e = new InvocationExpectation("onOpen",
+                    args -> predicate.apply((WebSocket) args[0]));
+            expectations.add(e);
+            return this;
+        }
+
+        Builder expectOnPing(F2<? super WebSocket, ? super ByteBuffer, Boolean> predicate) {
+            InvocationExpectation e = new InvocationExpectation("onPing",
+                    args -> predicate.apply((WebSocket) args[0], (ByteBuffer) args[1]));
+            expectations.add(e);
+            return this;
+        }
+
+        Builder expectOnClose(F3<? super WebSocket, ? super Integer, ? super String, Boolean> predicate) {
+            expectations.add(new InvocationExpectation("onClose",
+                    args -> predicate.apply((WebSocket) args[0], (Integer) args[1], (String) args[2])));
+            return this;
+        }
+
+        Builder expectOnError(F2<? super WebSocket, ? super Throwable, Boolean> predicate) {
+            expectations.add(new InvocationExpectation("onError",
+                    args -> predicate.apply((WebSocket) args[0], (Throwable) args[1])));
+            return this;
+        }
+
+        MockListener build() {
+            return new MockListener(new LinkedList<>(expectations));
+        }
+    }
+
+    private MockListener(List<InvocationExpectation> expectations) {
+        this.checker = new InvocationChecker(expectations);
+    }
+
+    @Override
+    public void onOpen(WebSocket webSocket) {
+        checker.checkInvocation("onOpen", webSocket);
+    }
+
+    @Override
+    public CompletionStage<?> onText(WebSocket webSocket, CharSequence message,
+                                     MessagePart part) {
+        checker.checkInvocation("onText", webSocket, message, part);
+        return null;
+    }
+
+    @Override
+    public CompletionStage<?> onBinary(WebSocket webSocket, ByteBuffer message,
+                                       MessagePart part) {
+        checker.checkInvocation("onBinary", webSocket, message, part);
+        return null;
+    }
+
+    @Override
+    public CompletionStage<?> onPing(WebSocket webSocket, ByteBuffer message) {
+        checker.checkInvocation("onPing", webSocket, message);
+        return null;
+    }
+
+    @Override
+    public CompletionStage<?> onPong(WebSocket webSocket, ByteBuffer message) {
+        checker.checkInvocation("onPong", webSocket, message);
+        return null;
+    }
+
+    @Override
+    public CompletionStage<?> onClose(WebSocket webSocket, int statusCode,
+                                      String reason) {
+        checker.checkInvocation("onClose", webSocket, statusCode, reason);
+        return null;
+    }
+
+    @Override
+    public void onError(WebSocket webSocket, Throwable error) {
+        checker.checkInvocation("onError", webSocket, error);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockListenerTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.Test;
+
+import jdk.incubator.http.internal.websocket.TestSupport.AssertionFailedException;
+import java.util.concurrent.TimeUnit;
+
+import static jdk.incubator.http.internal.websocket.TestSupport.assertThrows;
+import static jdk.incubator.http.internal.websocket.TestSupport.checkExpectations;
+
+public class MockListenerTest {
+
+    @Test
+    public void testPass01() {
+        MockListener l = new MockListener.Builder().build();
+        checkExpectations(1, TimeUnit.SECONDS, l);
+    }
+
+    @Test
+    public void testPass02() {
+        MockListener l = new MockListener.Builder()
+                .expectOnOpen(ws -> ws == null)
+                .build();
+        l.onOpen(null);
+        checkExpectations(1, TimeUnit.SECONDS, l);
+    }
+
+    @Test
+    public void testPass03() {
+        MockListener l = new MockListener.Builder()
+                .expectOnOpen(ws -> ws == null)
+                .expectOnClose((ws, code, reason) ->
+                        ws == null && code == 1002 && "blah".equals(reason))
+                .build();
+        l.onOpen(null);
+        l.onClose(null, 1002, "blah");
+        checkExpectations(1, TimeUnit.SECONDS, l);
+    }
+
+    @Test
+    public void testFail01() {
+        MockListener l = new MockListener.Builder()
+                .expectOnOpen(ws -> ws != null)
+                .build();
+        l.onOpen(null);
+        assertThrows(AssertionFailedException.class,
+                () -> checkExpectations(1, TimeUnit.SECONDS, l));
+    }
+
+    @Test
+    public void testFail02() {
+        MockListener l = new MockListener.Builder()
+                .expectOnOpen(ws -> true)
+                .build();
+        assertThrows(AssertionFailedException.class,
+                () -> checkExpectations(1, TimeUnit.SECONDS, l));
+    }
+
+    @Test
+    public void testFail03() {
+        MockListener l = new MockListener.Builder()
+                .expectOnOpen(ws -> true)
+                .build();
+        l.onOpen(null);
+        l.onClose(null, 1002, "");
+        assertThrows(AssertionFailedException.class,
+                () -> checkExpectations(1, TimeUnit.SECONDS, l));
+    }
+
+    @Test
+    public void testFail04() {
+        MockListener l = new MockListener.Builder().build();
+        l.onClose(null, 1002, "");
+        assertThrows(AssertionFailedException.class,
+                () -> checkExpectations(1, TimeUnit.SECONDS, l));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/PingTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.SkipException;
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+
+import java.io.IOException;
+import java.net.ProtocolException;
+import jdk.incubator.http.WebSocket;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static jdk.incubator.http.internal.websocket.TestSupport.Expectation.ifExpect;
+import static jdk.incubator.http.internal.websocket.TestSupport.assertCompletesExceptionally;
+import static jdk.incubator.http.internal.websocket.TestSupport.checkExpectations;
+import static org.testng.Assert.assertSame;
+
+/*
+ * Examines sendPing/onPing contracts
+ */
+public final class PingTest {
+
+    /*
+     * sendPing(message) is invoked. If the `message` argument is illegal, then
+     * the method must throw an appropriate exception. Otherwise no exception
+     * must be thrown.
+     */
+//    @Test(dataProvider = "outgoingData", dataProviderClass = DataProviders.class)
+    public void testSendPingArguments(ByteBuffer message) {
+        WebSocket ws = newWebSocket();
+        ifExpect(
+                message == null,
+                NullPointerException.class::isInstance)
+        .orExpect(
+                message != null && message.remaining() > 125,
+                IllegalArgumentException.class::isInstance)
+        .assertThrows(
+                () -> ws.sendPing(message)
+        );
+    }
+
+    /*
+     * sendPing(message) with a legal argument has been invoked, then:
+     *
+     * 1. A Ping message with the same payload appears on the wire
+     * 2. The CF returned from the method completes normally with the same
+     *    WebSocket that sendPing has been called on
+     */
+    @Test(dataProvider = "outgoingData", dataProviderClass = DataProviders.class)
+    public void testSendPingWysiwyg(ByteBuffer message) throws ExecutionException, InterruptedException {
+        if (message == null || message.remaining() > 125) {
+            return;
+        }
+        ByteBuffer snapshot = copy(message);
+        MockChannel channel = new MockChannel.Builder()
+                .expectPing(snapshot::equals)
+                .build();
+        WebSocket ws = newWebSocket(channel);
+        CompletableFuture<WebSocket> cf = ws.sendPing(message);
+        WebSocket ws1 = cf.join();
+        assertSame(ws1, ws); // (2)
+        checkExpectations(channel); // (1)
+    }
+
+    /*
+     * If an I/O error occurs while Ping messages is being sent, then:
+     *
+     * 1. The CF returned from sendPing completes exceptionally with this I/O
+     *    error as the cause
+     */
+//    @Test
+    public void testSendPingIOException() {
+        MockChannel ch = new MockChannel.Builder()
+//                .provideWriteException(IOException::new)
+                .build();
+        WebSocket ws = newWebSocket(ch);
+        CompletableFuture<WebSocket> cf = ws.sendPing(ByteBuffer.allocate(16));
+        assertCompletesExceptionally(IOException.class, cf);
+    }
+
+    /*
+     * If an incorrect Ping frame appears on the wire, then:
+     *
+     * 1. onError with the java.net.ProtocolException is invoked
+     * 1. A Close frame with status code 1002 appears on the wire
+     */
+//    @Test(dataProvider = "incorrectFrame", dataProviderClass = DataProviders.class)
+    public void testOnPingIncorrect(boolean fin, boolean rsv1, boolean rsv2,
+                                    boolean rsv3, ByteBuffer data) {
+        if (fin && !rsv1 && !rsv2 && !rsv3 && data.remaining() <= 125) {
+            throw new SkipException("Correct frame");
+        }
+        CompletableFuture<WebSocket> webSocket = new CompletableFuture<>();
+        MockChannel channel = new MockChannel.Builder()
+                .provideFrame(fin, rsv1, rsv2, rsv3, Opcode.PING, data)
+                .expectClose((code, reason) ->
+                        Integer.valueOf(1002).equals(code) && "".equals(reason))
+                .build();
+        MockListener listener = new MockListener.Builder()
+                .expectOnOpen((ws) -> true)
+                .expectOnError((ws, error) -> error instanceof ProtocolException)
+                .build();
+        webSocket.complete(newWebSocket(channel, listener));
+        checkExpectations(500, TimeUnit.MILLISECONDS, channel, listener);
+    }
+
+    /*
+     * If a Ping message has been read off the wire, then:
+     *
+     * 1. onPing is invoked with the data and the WebSocket the listener has
+     *    been attached to
+     * 2. A Pong message with the same contents will be sent in reply
+     */
+    @Test(dataProvider = "incomingData", dataProviderClass = DataProviders.class)
+    public void testOnPingReply(ByteBuffer data) {
+        CompletableFuture<WebSocket> webSocket = new CompletableFuture<>();
+        MockChannel channel = new MockChannel.Builder()
+                .provideFrame(true, false, false, false, Opcode.PING, data)
+                .expectPong(data::equals)
+                .build();
+        MockListener listener = new MockListener.Builder()
+                .expectOnOpen((ws) -> true) // maybe should capture with a CF?
+                .expectOnPing((ws, bb) -> data.equals(bb))
+                .build();
+        webSocket.complete(newWebSocket(channel, listener));
+        checkExpectations(500, TimeUnit.MILLISECONDS, channel, listener);
+    }
+
+    /*
+     * If onPing throws an exception or CS returned from it completes
+     * exceptionally, then:
+     *
+     * 1. onError is invoked with this particular exception as the cause and the
+     *    WebSocket the listener has been attached to
+     */
+    public void testOnPingExceptions() {
+    }
+
+    /*
+     * If a Ping message has been read off the wire and an I/O error occurs
+     * while WebSocket sends a Pong reply to it, then:
+     *
+     * 1. onError is invoked with this error as the cause and the WebSocket this
+     *    listener has been attached to
+     */
+    public void testOnPingReplyIOException() {
+    }
+
+    private WebSocket newWebSocket() {
+        return newWebSocket(new MockChannel.Builder().build());
+    }
+
+    private WebSocket newWebSocket(RawChannel ch) {
+        return newWebSocket(ch, new WebSocket.Listener() { });
+    }
+
+    private WebSocket newWebSocket(RawChannel ch, WebSocket.Listener l) {
+//        WebSocketImpl ws = new WebSocketImpl("", ch, l, Executors.newCachedThreadPool());
+//        ws.();
+//        ws.request(Long.MAX_VALUE);
+        return null; // FIXME
+    }
+
+    public static ByteBuffer copy(ByteBuffer src) {
+        int pos = src.position();
+        ByteBuffer b = ByteBuffer.allocate(src.remaining()).put(src).flip();
+        src.position(pos);
+        return b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/ReaderTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http.internal.websocket;
+
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.websocket.Frame.Opcode;
+
+import java.nio.ByteBuffer;
+import java.util.Optional;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+import java.util.function.IntPredicate;
+import java.util.function.IntUnaryOperator;
+
+import static java.util.OptionalInt.empty;
+import static java.util.OptionalInt.of;
+import static org.testng.Assert.assertEquals;
+import static jdk.incubator.http.internal.websocket.TestSupport.assertThrows;
+import static jdk.incubator.http.internal.websocket.TestSupport.forEachBufferPartition;
+
+public class ReaderTest {
+
+    private long cases, frames;
+
+    @Test
+    void notMinimalEncoding01() {
+        ByteBuffer h = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES);
+        h.put((byte) 0b1000_0000).put((byte) 0b0111_1110).putChar((char) 125).flip();
+        assertThrows(FailWebSocketException.class,
+                ".*(?i)minimally-encoded.*",
+                () -> new Frame.Reader().readFrame(h, new MockConsumer()));
+    }
+
+    @Test
+    void notMinimalEncoding02() {
+        ByteBuffer h = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES);
+        h.put((byte) 0b1000_0000).put((byte) 0b0111_1111).putLong(125).flip();
+        assertThrows(FailWebSocketException.class,
+                ".*(?i)minimally-encoded.*",
+                () -> new Frame.Reader().readFrame(h, new MockConsumer()));
+    }
+
+    @Test
+    void notMinimalEncoding03() {
+        ByteBuffer h = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES);
+        h.put((byte) 0b1000_0000).put((byte) 0b0111_1111).putLong(65535).flip();
+        assertThrows(FailWebSocketException.class,
+                ".*(?i)minimally-encoded.*",
+                () -> new Frame.Reader().readFrame(h, new MockConsumer()));
+    }
+
+    @Test
+    public void negativePayload() {
+        ByteBuffer h = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES);
+        h.put((byte) 0b1000_0000).put((byte) 0b0111_1111).putLong(-2L).flip();
+        assertThrows(FailWebSocketException.class,
+                ".*(?i)negative.*",
+                () -> new Frame.Reader().readFrame(h, new MockConsumer()));
+    }
+
+    @Test
+    public void frameStart() {
+        final long[] payloads = {0, 126, 65536, Integer.MAX_VALUE + 1L};
+        final OptionalInt[] masks = {empty(), of(-1), of(0), of(0xCAFEBABE),
+                of(Integer.MAX_VALUE), of(Integer.MIN_VALUE)};
+        for (boolean fin : new boolean[]{true, false}) {
+            for (boolean rsv1 : new boolean[]{true, false}) {
+                for (boolean rsv2 : new boolean[]{true, false}) {
+                    for (boolean rsv3 : new boolean[]{true, false}) {
+                        for (Opcode opcode : Opcode.values()) {
+                            for (long payloadLen : payloads) {
+                                for (OptionalInt mask : masks) {
+                                    verifyFrameStart(fin, rsv1, rsv2, rsv3, opcode, payloadLen, mask);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        System.out.println("Frames: " + frames + ", Total cases: " + cases);
+    }
+
+    /*
+     * Tests whether or not the frame starts properly.
+     * That is, a header and the first invocation of payloadData (if any).
+     */
+    private void verifyFrameStart(boolean fin,
+                                  boolean rsv1,
+                                  boolean rsv2,
+                                  boolean rsv3,
+                                  Opcode opcode,
+                                  long payloadLen,
+                                  OptionalInt mask) {
+        frames++;
+        Frame.HeaderWriter w = new Frame.HeaderWriter();
+        ByteBuffer h = ByteBuffer.allocate(Frame.MAX_HEADER_SIZE_BYTES);
+        w.fin(fin).rsv1(rsv1).rsv2(rsv2).rsv3(rsv3).opcode(opcode).payloadLen(payloadLen);
+        mask.ifPresentOrElse(w::mask, w::noMask);
+        w.write(h);
+        h.flip();
+        forEachBufferPartition(h,
+                buffers -> {
+                    cases++;
+                    Frame.Reader r = new Frame.Reader();
+                    MockConsumer c = new MockConsumer();
+                    for (ByteBuffer b : buffers) {
+                        r.readFrame(b, c);
+                    }
+                    assertEquals(fin, c.fin());
+                    assertEquals(rsv1, c.rsv1());
+                    assertEquals(rsv2, c.rsv2());
+                    assertEquals(rsv3, c.rsv3());
+                    assertEquals(opcode, c.opcode());
+                    assertEquals(mask.isPresent(), c.mask());
+                    assertEquals(payloadLen, c.payloadLen());
+                    assertEquals(mask, c.maskingKey());
+                    assertEquals(payloadLen == 0, c.isEndFrame());
+                });
+    }
+
+    /*
+     * Used to verify the order, the number of invocations as well as the
+     * arguments of each individual invocation to Frame.Consumer's methods.
+     */
+    private static class MockConsumer implements Frame.Consumer {
+
+        private int invocationOrder;
+
+        private Optional<Boolean> fin = Optional.empty();
+        private Optional<Boolean> rsv1 = Optional.empty();
+        private Optional<Boolean> rsv2 = Optional.empty();
+        private Optional<Boolean> rsv3 = Optional.empty();
+        private Optional<Opcode> opcode = Optional.empty();
+        private Optional<Boolean> mask = Optional.empty();
+        private OptionalLong payloadLen = OptionalLong.empty();
+        private OptionalInt maskingKey = OptionalInt.empty();
+
+        @Override
+        public void fin(boolean value) {
+            checkAndSetOrder(0, 1);
+            fin = Optional.of(value);
+        }
+
+        @Override
+        public void rsv1(boolean value) {
+            checkAndSetOrder(1, 2);
+            rsv1 = Optional.of(value);
+        }
+
+        @Override
+        public void rsv2(boolean value) {
+            checkAndSetOrder(2, 3);
+            rsv2 = Optional.of(value);
+        }
+
+        @Override
+        public void rsv3(boolean value) {
+            checkAndSetOrder(3, 4);
+            rsv3 = Optional.of(value);
+        }
+
+        @Override
+        public void opcode(Opcode value) {
+            checkAndSetOrder(4, 5);
+            opcode = Optional.of(value);
+        }
+
+        @Override
+        public void mask(boolean value) {
+            checkAndSetOrder(5, 6);
+            mask = Optional.of(value);
+        }
+
+        @Override
+        public void payloadLen(long value) {
+            checkAndSetOrder(p -> p == 5 || p == 6, n -> 7);
+            payloadLen = OptionalLong.of(value);
+        }
+
+        @Override
+        public void maskingKey(int value) {
+            checkAndSetOrder(7, 8);
+            maskingKey = of(value);
+        }
+
+        @Override
+        public void payloadData(ByteBuffer data) {
+            checkAndSetOrder(p -> p == 7 || p == 8, n -> 9);
+            assert payloadLen.isPresent();
+            if (payloadLen.getAsLong() != 0 && !data.hasRemaining()) {
+                throw new TestSupport.AssertionFailedException("Artefact of reading");
+            }
+        }
+
+        @Override
+        public void endFrame() {
+            checkAndSetOrder(9, 10);
+        }
+
+        boolean isEndFrame() {
+            return invocationOrder == 10;
+        }
+
+        public boolean fin() {
+            return fin.get();
+        }
+
+        public boolean rsv1() {
+            return rsv1.get();
+        }
+
+        public boolean rsv2() {
+            return rsv2.get();
+        }
+
+        public boolean rsv3() {
+            return rsv3.get();
+        }
+
+        public Opcode opcode() {
+            return opcode.get();
+        }
+
+        public boolean mask() {
+            return mask.get();
+        }
+
+        public long payloadLen() {
+            return payloadLen.getAsLong();
+        }
+
+        public OptionalInt maskingKey() {
+            return maskingKey;
+        }
+
+        private void checkAndSetOrder(int expectedValue, int newValue) {
+            checkAndSetOrder(p -> p == expectedValue, n -> newValue);
+        }
+
+        private void checkAndSetOrder(IntPredicate expectedValue,
+                                      IntUnaryOperator newValue) {
+            if (!expectedValue.test(invocationOrder)) {
+                throw new TestSupport.AssertionFailedException(
+                        expectedValue + " -> " + newValue);
+            }
+            invocationOrder = newValue.applyAsInt(invocationOrder);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/TestSupport.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,535 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http.internal.websocket;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.List.of;
+import static java.util.Objects.requireNonNull;
+
+/*
+ * Auxiliary test infrastructure
+ */
+final class TestSupport {
+
+    private TestSupport() { }
+
+    static <A, B, R> Iterator<R> cartesianIterator(List<A> a,
+                                                   List<B> b,
+                                                   F2<A, B, R> f2) {
+        @SuppressWarnings("unchecked")
+        F<R> t = p -> f2.apply((A) p[0], (B) p[1]);
+        return cartesianIterator(of(a, b), t);
+    }
+
+    static <A, B, C, R> Iterator<R> cartesianIterator(List<A> a,
+                                                      List<B> b,
+                                                      List<C> c,
+                                                      F3<A, B, C, R> f3) {
+        @SuppressWarnings("unchecked")
+        F<R> t = p -> f3.apply((A) p[0], (B) p[1], (C) p[2]);
+        return cartesianIterator(of(a, b, c), t);
+    }
+
+    static <A, B, C, D, R> Iterator<R> cartesianIterator(List<A> a,
+                                                         List<B> b,
+                                                         List<C> c,
+                                                         List<D> d,
+                                                         F4<A, B, C, D, R> f4) {
+        @SuppressWarnings("unchecked")
+        F<R> t = p -> f4.apply((A) p[0], (B) p[1], (C) p[2], (D) p[3]);
+        return cartesianIterator(of(a, b, c, d), t);
+    }
+
+    static <A, B, C, D, E, R> Iterator<R> cartesianIterator(List<A> a,
+                                                            List<B> b,
+                                                            List<C> c,
+                                                            List<D> d,
+                                                            List<E> e,
+                                                            F5<A, B, C, D, E, R> f5) {
+        @SuppressWarnings("unchecked")
+        F<R> t = p -> f5.apply((A) p[0], (B) p[1], (C) p[2], (D) p[3], (E) p[4]);
+        return cartesianIterator(of(a, b, c, d, e), t);
+    }
+
+    static <R> Iterator<R> cartesianIterator(List<? extends List<?>> params,
+                                             F<R> function) {
+        if (params.isEmpty()) {
+            return Collections.emptyIterator();
+        }
+        for (List<?> l : params) {
+            if (l.isEmpty()) {
+                return Collections.emptyIterator();
+            }
+        }
+        // Assertion: if we are still here, there is at least a single element
+        // in the product
+        return new Iterator<>() {
+
+            private final int arity = params.size();
+            private final int[] coordinates = new int[arity];
+            private boolean hasNext = true;
+
+            @Override
+            public boolean hasNext() {
+                return hasNext;
+            }
+
+            @Override
+            public R next() {
+                if (!hasNext) {
+                    throw new NoSuchElementException();
+                }
+                Object[] array = new Object[arity];
+                for (int i = 0; i < arity; i++) {
+                    array[i] = params.get(i).get(coordinates[i]);
+                }
+                int p = arity - 1;
+                while (p >= 0 && coordinates[p] == params.get(p).size() - 1) {
+                    p--;
+                }
+                if (p < 0) {
+                    hasNext = false;
+                } else {
+                    coordinates[p]++;
+                    for (int i = p + 1; i < arity; i++) {
+                        coordinates[i] = 0;
+                    }
+                }
+                return function.apply(array);
+            }
+        };
+    }
+
+    @FunctionalInterface
+    public interface F1<A, R> {
+        R apply(A a);
+    }
+
+    @FunctionalInterface
+    public interface F2<A, B, R> {
+        R apply(A a, B b);
+    }
+
+    @FunctionalInterface
+    public interface F3<A, B, C, R> {
+        R apply(A a, B b, C c);
+    }
+
+    @FunctionalInterface
+    public interface F4<A, B, C, D, R> {
+        R apply(A a, B b, C c, D d);
+    }
+
+    @FunctionalInterface
+    public interface F5<A, B, C, D, E, R> {
+        R apply(A a, B b, C c, D d, E e);
+    }
+
+    @FunctionalInterface
+    public interface F<R> {
+        R apply(Object[] args);
+    }
+
+    static <T> Iterator<T> iteratorOf1(T element) {
+        return List.of(element).iterator();
+    }
+
+    @SafeVarargs
+    static <T> Iterator<T> iteratorOf(T... elements) {
+        return List.of(elements).iterator();
+    }
+
+    static <T> Iterator<T> limit(int maxElements, Iterator<? extends T> elements) {
+        return new Iterator<>() {
+
+            int count = maxElements;
+
+            @Override
+            public boolean hasNext() {
+                return count > 0 && elements.hasNext();
+            }
+
+            @Override
+            public T next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                count--;
+                return elements.next();
+            }
+        };
+    }
+
+//    static <T> Iterator<T> filter(Iterator<? extends T> source,
+//                                  Predicate<? super T> predicate) {
+//        return new Iterator<>() {
+//
+//            { findNext(); }
+//
+//            T next;
+//            boolean hasNext;
+//
+//            @Override
+//            public boolean hasNext() {
+//                return hasNext;
+//            }
+//
+//            @Override
+//            public T next() {
+//                if (!hasNext) {
+//                    throw new NoSuchElementException();
+//                }
+//                T n = this.next;
+//                findNext();
+//                return n;
+//            }
+//
+//            void findNext() {
+//                while (source.hasNext()) {
+//                    T n = source.next();
+//                    if (predicate.test(n)) {
+//                        hasNext = true;
+//                        next = n;
+//                        break;
+//                    }
+//                }
+//            }
+//        };
+//    }
+
+    static ByteBuffer fullCopy(ByteBuffer src) {
+        ByteBuffer copy = ByteBuffer.allocate(src.capacity());
+        int p = src.position();
+        int l = src.limit();
+        src.clear();
+        copy.put(src).position(p).limit(l);
+        src.position(p).limit(l);
+        return copy;
+    }
+
+    static void forEachBufferPartition(ByteBuffer src,
+                                       Consumer<? super Iterable<? extends ByteBuffer>> action) {
+        forEachPartition(src.remaining(),
+                (lengths) -> {
+                    int end = src.position();
+                    List<ByteBuffer> buffers = new LinkedList<>();
+                    for (int len : lengths) {
+                        ByteBuffer d = src.duplicate();
+                        d.position(end);
+                        d.limit(end + len);
+                        end += len;
+                        buffers.add(d);
+                    }
+                    action.accept(buffers);
+                });
+    }
+
+    private static void forEachPartition(int n,
+                                         Consumer<? super Iterable<Integer>> action) {
+        forEachPartition(n, new Stack<>(), action);
+    }
+
+    private static void forEachPartition(int n,
+                                         Stack<Integer> path,
+                                         Consumer<? super Iterable<Integer>> action) {
+        if (n == 0) {
+            action.accept(path);
+        } else {
+            for (int i = 1; i <= n; i++) {
+                path.push(i);
+                forEachPartition(n - i, path, action);
+                path.pop();
+            }
+        }
+    }
+
+    static void forEachPermutation(int n, Consumer<? super int[]> c) {
+        int[] a = new int[n];
+        for (int i = 0; i < n; i++) {
+            a[i] = i;
+        }
+        permutations(0, a, c);
+    }
+
+    private static void permutations(int i, int[] a, Consumer<? super int[]> c) {
+        if (i == a.length) {
+            c.accept(Arrays.copyOf(a, a.length));
+            return;
+        }
+        for (int j = i; j < a.length; j++) {
+            swap(a, i, j);
+            permutations(i + 1, a, c);
+            swap(a, i, j);
+        }
+    }
+
+    private static void swap(int[] a, int i, int j) {
+        int x = a[i];
+        a[i] = a[j];
+        a[j] = x;
+    }
+
+    static <T> Iterator<T> concat(Iterator<? extends Iterator<? extends T>> iterators) {
+        requireNonNull(iterators);
+        return new Iterator<>() {
+
+            private Iterator<? extends T> current = Collections.emptyIterator();
+
+            @Override
+            public boolean hasNext() {
+                while (!current.hasNext()) {
+                    if (!iterators.hasNext()) {
+                        return false;
+                    } else {
+                        current = iterators.next();
+                    }
+                }
+                return true;
+            }
+
+            @Override
+            public T next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                return current.next();
+            }
+        };
+    }
+
+    interface Mock {
+
+        /*
+         * Completes exceptionally if there are any expectations that haven't
+         * been met within the given time period, otherwise completes normally
+         */
+        CompletableFuture<Void> expectations(long timeout, TimeUnit unit);
+    }
+
+    static final class InvocationChecker {
+
+        private final Object lock = new Object();
+        private final Iterator<InvocationExpectation> expectations;
+        private final CompletableFuture<Void> expectationsViolation
+                = new CompletableFuture<>();
+
+        InvocationChecker(Iterable<InvocationExpectation> expectations) {
+            this.expectations = requireNonNull(expectations).iterator();
+        }
+
+        /*
+         * Completes exceptionally if there are any expectations that haven't
+         * been met within the given time period, otherwise completes normally
+         */
+        CompletableFuture<Void> expectations(long timeout, TimeUnit unit) {
+            return expectationsViolation
+                    .orTimeout(timeout, unit)
+                    .handle((v, t) -> {
+                        if (t == null) {
+                            throw new InternalError(
+                                    "Unexpected normal completion: " + v);
+                        } else if (t instanceof TimeoutException) {
+                            synchronized (lock) {
+                                if (!expectations.hasNext()) {
+                                    return null;
+                                } else {
+                                    throw new AssertionFailedException(
+                                            "More invocations were expected");
+                                }
+                            }
+                        } else if (t instanceof AssertionFailedException) {
+                            throw (AssertionFailedException) t;
+                        } else {
+                            throw new RuntimeException(t);
+                        }
+                    });
+        }
+
+        void checkInvocation(String name, Object... args) {
+            synchronized (lock) {
+                if (!expectations.hasNext()) {
+                    expectationsViolation.completeExceptionally(
+                            new AssertionFailedException(
+                                    "Less invocations were expected: " + name));
+                    return;
+                }
+                InvocationExpectation next = expectations.next();
+                if (!next.name.equals(name)) {
+                    expectationsViolation.completeExceptionally(
+                            new AssertionFailedException(
+                                    "A different invocation was expected: " + name)
+                    );
+                    return;
+                }
+                if (!next.predicate.apply(args)) {
+                    expectationsViolation.completeExceptionally(
+                            new AssertionFailedException(
+                                    "Invocation doesn't match the predicate: "
+                                            + name + ", " + Arrays.toString(args))
+                    );
+                }
+            }
+        }
+    }
+
+    static final class InvocationExpectation {
+
+        final String name;
+        final F<Boolean> predicate;
+
+        InvocationExpectation(String name, F<Boolean> predicate) {
+            this.name = requireNonNull(name);
+            this.predicate = requireNonNull(predicate);
+        }
+    }
+
+    static void checkExpectations(Mock... mocks) {
+        checkExpectations(0, TimeUnit.SECONDS, mocks);
+    }
+
+    static void checkExpectations(long timeout, TimeUnit unit, Mock... mocks) {
+        CompletableFuture<?>[] completableFutures = Stream.of(mocks)
+                .map(m -> m.expectations(timeout, unit))
+                .collect(Collectors.toList()).toArray(new CompletableFuture<?>[0]);
+        CompletableFuture<Void> cf = CompletableFuture.allOf(completableFutures);
+        try {
+            cf.join();
+        } catch (CompletionException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof AssertionFailedException) {
+                throw (AssertionFailedException) cause;
+            } else {
+                throw e;
+            }
+        }
+    }
+
+    public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
+                                                       ThrowingProcedure code) {
+        @SuppressWarnings("unchecked")
+        T t = (T) assertThrows(clazz::isInstance, code);
+        return t;
+    }
+
+    /*
+     * The rationale behind asking for a regex is to not pollute variable names
+     * space in the scope of assertion: if it's something as simple as checking
+     * a message, we can do it inside
+     */
+    @SuppressWarnings("unchecked")
+    static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
+                                                String messageRegex,
+                                                ThrowingProcedure code) {
+        requireNonNull(messageRegex, "messagePattern");
+        Predicate<Throwable> p = e -> clazz.isInstance(e)
+                && Pattern.matches(messageRegex, e.getMessage());
+        return (T) assertThrows(p, code);
+    }
+
+    static Throwable assertThrows(Predicate<? super Throwable> predicate,
+                                  ThrowingProcedure code) {
+        requireNonNull(predicate, "predicate");
+        requireNonNull(code, "code");
+        Throwable caught = null;
+        try {
+            code.run();
+        } catch (Throwable t) {
+            caught = t;
+        }
+        if (predicate.test(caught)) {
+            return caught;
+        }
+        if (caught == null) {
+            throw new AssertionFailedException("No exception was thrown");
+        }
+        throw new AssertionFailedException("Caught exception didn't match the predicate", caught);
+    }
+
+    /*
+     * Blocking assertion, waits for completion
+     */
+    static Throwable assertCompletesExceptionally(Class<? extends Throwable> clazz,
+                                                  CompletionStage<?> stage) {
+        CompletableFuture<?> cf =
+                CompletableFuture.completedFuture(null).thenCompose(x -> stage);
+        return assertThrows(t -> clazz.isInstance(t.getCause()), cf::get);
+    }
+
+    interface ThrowingProcedure {
+        void run() throws Throwable;
+    }
+
+    static final class Expectation {
+
+        private final List<Predicate<? super Throwable>> list = new LinkedList<>();
+
+        static Expectation ifExpect(boolean condition,
+                                    Predicate<? super Throwable> predicate) {
+            return addPredicate(new Expectation(), condition, predicate);
+        }
+
+        Expectation orExpect(boolean condition,
+                             Predicate<? super Throwable> predicate) {
+            return addPredicate(this, condition, predicate);
+        }
+
+        static Expectation addPredicate(Expectation e, boolean condition,
+                                        Predicate<? super Throwable> predicate) {
+            if (condition) {
+                e.list.add(requireNonNull(predicate));
+            }
+            return e;
+        }
+
+        public Throwable assertThrows(ThrowingProcedure code) {
+            Predicate<Throwable> p;
+            if (list.isEmpty()) {
+                p = Objects::isNull;
+            } else {
+                p = e -> list.stream().anyMatch(x -> x.test(e));
+            }
+            return TestSupport.assertThrows(p, code);
+        }
+    }
+
+    static final class AssertionFailedException extends RuntimeException {
+
+        private static final long serialVersionUID = 1L;
+
+        AssertionFailedException(String message) {
+            super(message);
+        }
+
+        AssertionFailedException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+}
--- a/jdk/test/java/net/httpclient/whitebox/Driver.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/net/httpclient/whitebox/Driver.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,8 @@
 
 /*
  * @test
- * @bug 8151299
- * @modules java.httpclient
- * @run testng java.httpclient/java.net.http.SelectorTest
+ * @bug 8151299 8164704
+ * @modules jdk.incubator.httpclient
+ * @run testng jdk.incubator.httpclient/jdk.incubator.http.SelectorTest
+ * @run testng jdk.incubator.httpclient/jdk.incubator.http.ResponseHeadersTest
  */
--- a/jdk/test/java/net/httpclient/whitebox/java.httpclient/java/net/http/SelectorTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net.http;
-
-import java.net.*;
-import java.io.*;
-import java.nio.channels.*;
-import java.nio.ByteBuffer;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicInteger;
-import static java.lang.System.out;
-import static java.nio.charset.StandardCharsets.US_ASCII;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import org.testng.annotations.Test;
-
-/**
- * Whitebox test of selector mechanics. Currently only a simple test
- * setting one read and one write event is done. It checks that the
- * write event occurs first, followed by the read event and then no
- * further events occur despite the conditions actually still existing.
- */
-@Test
-public class SelectorTest {
-
-    AtomicInteger counter = new AtomicInteger();
-    volatile boolean error;
-    static final CountDownLatch finishingGate = new CountDownLatch(1);
-
-    String readSomeBytes(RawChannel chan) {
-        try {
-            ByteBuffer buf = ByteBuffer.allocate(1024);
-            int t = chan.read(buf);
-            if (t <= 0) {
-                out.printf("chan read returned %d\n", t);
-                return null;
-            }
-            byte[] bb = new byte[t];
-            buf.get(bb);
-            return new String(bb, US_ASCII);
-        } catch (IOException ioe) {
-            throw new UncheckedIOException(ioe);
-        }
-    }
-
-    @Test(timeOut = 10000)
-    public void test() throws Exception {
-
-        try (ServerSocket server = new ServerSocket(0)) {
-            int port = server.getLocalPort();
-
-            out.println("Listening on port " + server.getLocalPort());
-
-            TestServer t = new TestServer(server);
-            t.start();
-            out.println("Started server thread");
-
-            final RawChannel chan = getARawChannel(port);
-
-            chan.registerEvent(new RawChannel.RawEvent() {
-                @Override
-                public int interestOps() {
-                    return SelectionKey.OP_READ;
-                }
-
-                @Override
-                public void handle() {
-                    readSomeBytes(chan);
-                    out.printf("OP_READ\n");
-                    if (counter.get() != 1) {
-                        out.printf("OP_READ error counter = %d\n", counter);
-                        error = true;
-                    }
-                }
-            });
-
-            chan.registerEvent(new RawChannel.RawEvent() {
-                @Override
-                public int interestOps() {
-                    return SelectionKey.OP_WRITE;
-                }
-
-                @Override
-                public void handle() {
-                    out.printf("OP_WRITE\n");
-                    if (counter.get() != 0) {
-                        out.printf("OP_WRITE error counter = %d\n", counter);
-                        error = true;
-                    } else {
-                        ByteBuffer bb = ByteBuffer.wrap(TestServer.INPUT);
-                        counter.incrementAndGet();
-                        try {
-                            chan.write(new ByteBuffer[]{bb}, 0, 1);
-                        } catch (IOException e) {
-                            throw new UncheckedIOException(e);
-                        }
-                    }
-                }
-
-            });
-            out.println("Events registered. Waiting");
-            finishingGate.await(30, SECONDS);
-            if (error)
-                throw new RuntimeException("Error");
-            else
-                out.println("No error");
-        }
-    }
-
-    static RawChannel getARawChannel(int port) throws Exception {
-        URI uri = URI.create("http://127.0.0.1:" + port + "/");
-        out.println("client connecting to " + uri.toString());
-        HttpRequest req = HttpRequest.create(uri).GET();
-        HttpResponse r = req.response();
-        r.body(HttpResponse.ignoreBody());
-        return ((HttpResponseImpl) r).rawChannel();
-    }
-
-    static class TestServer extends Thread {
-        static final byte[] INPUT = "Hello world".getBytes(US_ASCII);
-        static final byte[] OUTPUT = "Goodbye world".getBytes(US_ASCII);
-        static final String FIRST_RESPONSE = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n";
-        final ServerSocket server;
-
-        TestServer(ServerSocket server) throws IOException {
-            this.server = server;
-        }
-
-        public void run() {
-            try (Socket s = server.accept();
-                 InputStream is = s.getInputStream();
-                 OutputStream os = s.getOutputStream()) {
-
-                out.println("Got connection");
-                readRequest(is);
-                os.write(FIRST_RESPONSE.getBytes());
-                read(is);
-                write(os);
-                Thread.sleep(1000);
-                // send some more data, and make sure WRITE op does not get called
-                write(os);
-                out.println("TestServer exiting");
-                SelectorTest.finishingGate.countDown();
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
-        // consumes the HTTP request
-        static void readRequest(InputStream is) throws IOException {
-            out.println("starting readRequest");
-            byte[] buf = new byte[1024];
-            String s = "";
-            while (true) {
-                int n = is.read(buf);
-                if (n <= 0)
-                    throw new IOException("Error");
-                s = s + new String(buf, 0, n);
-                if (s.indexOf("\r\n\r\n") != -1)
-                    break;
-            }
-            out.println("returning from readRequest");
-        }
-
-        static void read(InputStream is) throws IOException {
-            out.println("starting read");
-            for (int i = 0; i < INPUT.length; i++) {
-                int c = is.read();
-                if (c == -1)
-                    throw new IOException("closed");
-                if (INPUT[i] != (byte) c)
-                    throw new IOException("Error. Expected:" + INPUT[i] + ", got:" + c);
-            }
-            out.println("returning from read");
-        }
-
-        static void write(OutputStream os) throws IOException {
-            out.println("doing write");
-            os.write(OUTPUT);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/ResponseHeadersTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.http;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.common.ByteBufferReference;
+
+@Test
+public class ResponseHeadersTest {
+
+    static final String BODY =
+          "This is the body dude,\r\n"
+        + "not a header!\r\n";
+
+    static final String MESSAGE_OK =
+          "HTTP/1.1 200 OK\r\n"
+        + "Content-Length: " + BODY.length() + "\r\n"
+        + "MY-Folding-Header: YES\r\n"
+        + " OR\r\n"
+        + " NO\r\n"
+        + "\r\n"
+        + BODY;
+
+    static final String MESSAGE_NOK =
+          "HTTP/1.1 101 Switching Protocols\r\n"
+        + "\r\n";
+
+    //public static void main(String[] args) throws IOException {
+    //    new  ResponseHeadersTest().test();
+    //}
+
+    @Test
+    public void test() throws IOException {
+        testResponseHeaders(MESSAGE_OK);
+        testResponseHeaders(MESSAGE_NOK);
+    }
+
+    /**
+     * Verifies that ResponseHeaders behave as we expect.
+     * @param msg The response string.
+     * @throws IOException should not happen.
+     */
+    static void testResponseHeaders(String msg) throws IOException {
+        byte[] bytes = msg.getBytes("US-ASCII");
+        ByteBuffer buffer = ByteBuffer.wrap(bytes);
+
+        // Read status line
+        String statusLine = readStatusLine(buffer);
+        System.out.println("StatusLine: " + statusLine);
+        if (!statusLine.startsWith("HTTP/1.1")) {
+            throw new AssertionError("bad status line: " + statusLine);
+        }
+
+        // We have two cases:
+        //    - MESSAGE_OK: there will be some headers to read,
+        //    - MESSAGE_NOK: there will be no headers to read.
+        HttpHeaders headers = createResponseHeaders(buffer);
+
+        // Now get the expected length of the body
+        Optional<String> contentLengthValue = headers.firstValue("Content-length");
+        int contentLength = contentLengthValue.map(Integer::parseInt).orElse(0);
+
+        // We again have two cases:
+        //    - MESSAGE_OK:  there should be a Content-length: header
+        //    - MESSAGE_NOK: there should be no Content-length: header
+        if (contentLengthValue.isPresent()) {
+            // MESSAGE_NOK has no headers and no body and therefore
+            // no Content-length: header.
+            if (MESSAGE_NOK.equals(msg)) {
+                throw new AssertionError("Content-length: header found in"
+                          + " error 101 message");
+            }
+        } else {
+            if (!MESSAGE_NOK.equals(msg)) {
+                throw new AssertionError("Content-length: header not found");
+            }
+        }
+
+        // Now read the remaining bytes. It should either be
+        // the empty string (MESSAGE_NOK) or BODY (MESSAGE_OK),
+        // and it should not contains any leading CR or LF"
+        String remaining = readRemainingBytes(buffer);
+        System.out.println("Body: <<<" + remaining + ">>>");
+        if (remaining.length() != contentLength) {
+            throw new AssertionError("Unexpected body length: " + remaining.length()
+                     + " expected " + contentLengthValue);
+        }
+        if (contentLengthValue.isPresent()) {
+            if (!BODY.equals(remaining)) {
+                throw new AssertionError("Body does not match!");
+            }
+        }
+    }
+
+    static String readRemainingBytes(ByteBuffer buffer) throws UnsupportedEncodingException {
+        byte[] res = new byte[buffer.limit() - buffer.position()];
+        System.arraycopy(buffer.array(), buffer.position(), res, 0, res.length);
+        buffer.position(buffer.limit());
+        return new String(res, "US-ASCII");
+    }
+
+    static String readStatusLine(ByteBuffer buffer) throws IOException {
+        buffer.mark();
+        int p = buffer.position();
+        while(buffer.hasRemaining()) {
+            char c = (char)buffer.get();
+            if (c == '\r') {
+                c = (char)buffer.get();
+                if (c == '\n') {
+                    byte[] res = new byte[buffer.position() - p -2];
+                    System.arraycopy(buffer.array(), p, res, 0, res.length);
+                    return new String(res, "US-ASCII");
+                }
+            }
+        }
+        throw new IOException("Status line not found");
+    }
+
+    private static final class HttpConnectionStub extends HttpConnection {
+        public HttpConnectionStub() {
+            super(null, null);
+        }
+        @Override
+        public void connect() throws IOException, InterruptedException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        public CompletableFuture<Void> connectAsync() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        boolean connected() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        boolean isSecure() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        boolean isProxied() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        CompletableFuture<Void> whenReceivingResponse() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        SocketChannel channel() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        ConnectionPool.CacheKey cacheKey() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        long write(ByteBuffer[] buffers, int start, int number) throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        long write(ByteBuffer buffer) throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        void writeAsync(ByteBufferReference[] buffers) throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        void flushAsync() throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        public void close() {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        void shutdownInput() throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        void shutdownOutput() throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        protected ByteBuffer readImpl() throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+        @Override
+        protected int readImpl(ByteBuffer buffer) throws IOException {
+            throw new AssertionError("Bad test assumption: should not have reached here!");
+        }
+    }
+
+    public static HttpHeaders createResponseHeaders(ByteBuffer buffer)
+        throws IOException{
+        return new ResponseHeaders(new HttpConnectionStub(), buffer);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/SelectorTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.incubator.http;
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+import static java.lang.System.out;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static jdk.incubator.http.HttpResponse.BodyHandler.discard;
+
+import org.testng.annotations.Test;
+import jdk.incubator.http.internal.websocket.RawChannel;
+
+/**
+ * Whitebox test of selector mechanics. Currently only a simple test
+ * setting one read and one write event is done. It checks that the
+ * write event occurs first, followed by the read event and then no
+ * further events occur despite the conditions actually still existing.
+ */
+@Test
+public class SelectorTest {
+
+    AtomicInteger counter = new AtomicInteger();
+    volatile boolean error;
+    static final CountDownLatch finishingGate = new CountDownLatch(1);
+    static volatile HttpClient staticDefaultClient;
+
+    static HttpClient defaultClient() {
+        if (staticDefaultClient == null) {
+            synchronized (SelectorTest.class) {
+                staticDefaultClient = HttpClient.newHttpClient();
+            }
+        }
+        return staticDefaultClient;
+    }
+
+    String readSomeBytes(RawChannel chan) {
+        try {
+            ByteBuffer buf = chan.read();
+            if (buf == null) {
+                out.println("chan read returned null");
+                return null;
+            }
+            buf.flip();
+            byte[] bb = new byte[buf.remaining()];
+            buf.get(bb);
+            return new String(bb, US_ASCII);
+        } catch (IOException ioe) {
+            throw new UncheckedIOException(ioe);
+        }
+    }
+
+    @Test(timeOut = 10000)
+    public void test() throws Exception {
+
+        try (ServerSocket server = new ServerSocket(0)) {
+            int port = server.getLocalPort();
+
+            out.println("Listening on port " + server.getLocalPort());
+
+            TestServer t = new TestServer(server);
+            t.start();
+            out.println("Started server thread");
+
+            final RawChannel chan = getARawChannel(port);
+
+            chan.registerEvent(new RawChannel.RawEvent() {
+                @Override
+                public int interestOps() {
+                    return SelectionKey.OP_READ;
+                }
+
+                @Override
+                public void handle() {
+                    readSomeBytes(chan);
+                    out.printf("OP_READ\n");
+                    final int count = counter.get();
+                    if (count != 1) {
+                        out.printf("OP_READ error counter = %d\n", count);
+                        error = true;
+                    }
+                }
+            });
+
+            chan.registerEvent(new RawChannel.RawEvent() {
+                @Override
+                public int interestOps() {
+                    return SelectionKey.OP_WRITE;
+                }
+
+                @Override
+                public void handle() {
+                    out.printf("OP_WRITE\n");
+                    final int count = counter.get();
+                    if (count != 0) {
+                        out.printf("OP_WRITE error counter = %d\n", count);
+                        error = true;
+                    } else {
+                        ByteBuffer bb = ByteBuffer.wrap(TestServer.INPUT);
+                        counter.incrementAndGet();
+                        try {
+                            chan.write(new ByteBuffer[]{bb}, 0, 1);
+                        } catch (IOException e) {
+                            throw new UncheckedIOException(e);
+                        }
+                    }
+                }
+
+            });
+            out.println("Events registered. Waiting");
+            finishingGate.await(30, SECONDS);
+            if (error)
+                throw new RuntimeException("Error");
+            else
+                out.println("No error");
+        }
+    }
+
+    static RawChannel getARawChannel(int port) throws Exception {
+        URI uri = URI.create("http://127.0.0.1:" + port + "/");
+        out.println("client connecting to " + uri.toString());
+        HttpRequest req = HttpRequest.newBuilder(uri).build();
+        HttpResponse<?> r = defaultClient().send(req, discard(null));
+        r.body();
+        return ((HttpResponseImpl) r).rawChannel();
+    }
+
+    static class TestServer extends Thread {
+        static final byte[] INPUT = "Hello world".getBytes(US_ASCII);
+        static final byte[] OUTPUT = "Goodbye world".getBytes(US_ASCII);
+        static final String FIRST_RESPONSE = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n";
+        final ServerSocket server;
+
+        TestServer(ServerSocket server) throws IOException {
+            this.server = server;
+        }
+
+        public void run() {
+            try (Socket s = server.accept();
+                 InputStream is = s.getInputStream();
+                 OutputStream os = s.getOutputStream()) {
+
+                out.println("Got connection");
+                readRequest(is);
+                os.write(FIRST_RESPONSE.getBytes());
+                read(is);
+                write(os);
+                Thread.sleep(1000);
+                // send some more data, and make sure WRITE op does not get called
+                write(os);
+                out.println("TestServer exiting");
+                SelectorTest.finishingGate.countDown();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        // consumes the HTTP request
+        static void readRequest(InputStream is) throws IOException {
+            out.println("starting readRequest");
+            byte[] buf = new byte[1024];
+            String s = "";
+            while (true) {
+                int n = is.read(buf);
+                if (n <= 0)
+                    throw new IOException("Error");
+                s = s + new String(buf, 0, n);
+                if (s.indexOf("\r\n\r\n") != -1)
+                    break;
+            }
+            out.println("returning from readRequest");
+        }
+
+        static void read(InputStream is) throws IOException {
+            out.println("starting read");
+            for (int i = 0; i < INPUT.length; i++) {
+                int c = is.read();
+                if (c == -1)
+                    throw new IOException("closed");
+                if (INPUT[i] != (byte) c)
+                    throw new IOException("Error. Expected:" + INPUT[i] + ", got:" + c);
+            }
+            out.println("returning from read");
+        }
+
+        static void write(OutputStream os) throws IOException {
+            out.println("doing write");
+            os.write(OUTPUT);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/FileExtensionAndMap.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @ignore This test has huge disk space requirements
+ * @bug 8168628
+ * @summary Test extending files to very large sizes without hitting a SIGBUS
+ * @requires (os.family == "linux")
+ * @run main/othervm/timeout=600 -Xms4g -Xmx4g FileExtensionAndMap
+ * @run main/othervm/timeout=600 -Xms4g -Xmx4g FileExtensionAndMap true
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Semaphore;
+import java.util.stream.IntStream;
+
+public class FileExtensionAndMap {
+
+    private static final ExecutorService CACHED_EXECUTORSERVICE =
+        Executors.newCachedThreadPool();
+
+    private static final String TMPDIR = System.getProperty("test.dir", ".");
+
+    private static boolean useRaf = false;
+
+    public static void main(String args[]) throws Exception {
+        if (args.length > 2) {
+            throw new IllegalArgumentException
+                ("Arguments: [true|false [targetFolder]]");
+        }
+
+        String defaultFolder = TMPDIR + File.separator + "target";
+        if (args.length > 0) {
+            useRaf = Boolean.valueOf(args[0]);
+            if (args.length > 1) {
+                defaultFolder = args[1];
+            }
+        }
+        final String targetFolder = defaultFolder;
+        Path p = Paths.get(targetFolder);
+        boolean targetExists = Files.exists(p);
+        if (!targetExists) {
+            Files.createDirectory(p);
+        }
+
+        System.out.printf("Using RandomAccessFile: %s; target folder: %s%n",
+            useRaf, targetFolder);
+
+        ForkJoinPool fjPool = new ForkJoinPool(3);
+        fjPool.submit(() -> {
+            IntStream.range(0, 20).parallel().forEach((index) -> {
+                String fileName = "testBigFile_" + index + ".dat";
+                Path source = null;
+                Path target = null;
+                try {
+                    source = Paths.get(TMPDIR, fileName);
+                    testCreateBigFile(source);
+                    target = Paths.get(targetFolder, fileName);
+                    testFileCopy(source, target);
+                } catch (Throwable th) {
+                    System.err.println("Error copying file with fileName: "
+                        + fileName + " : " + th.getMessage());
+                    th.printStackTrace(System.err);
+                } finally {
+                    try {
+                        if (source != null) {
+                            Files.deleteIfExists(source);
+                        }
+                    } catch (Throwable ignored) {
+                    }
+                    try {
+                        if (target != null) {
+                            Files.deleteIfExists(target);
+                        }
+                    } catch (Throwable ignored) {
+                    }
+                }
+            });
+        }).join();
+
+        if (!targetExists) {
+            Files.delete(p);
+        }
+    }
+
+    private static void testFileCopy(Path source, Path target)
+        throws IOException {
+        Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
+        System.out.println("Finished copying file with fileName: "
+                + source.getFileName());
+    }
+
+    private static void testCreateBigFile(Path segmentFile)
+        throws IOException {
+        final Semaphore concurrencySemaphore = new Semaphore(5);
+        long fileSize = 3L * 1024L * 1024L * 1024L;
+        int blockSize = 10 * 1024 * 1024;
+        int loopCount = (int) Math.floorDiv(fileSize, blockSize);
+
+        String fileName = segmentFile.getFileName().toString();
+        if (useRaf) {
+            try (RandomAccessFile raf
+                = new RandomAccessFile(segmentFile.toFile(), "rw")) {
+                raf.setLength(fileSize);
+                try (FileChannel fc = raf.getChannel()) {
+                    for (int i = 0; i < loopCount; i++) {
+                        final long startPosition = 1L * blockSize * i;
+                        concurrencySemaphore.acquireUninterruptibly();
+                        CACHED_EXECUTORSERVICE.submit(() -> {
+                            writeTemplateData(fileName, fc, startPosition,
+                                    blockSize, concurrencySemaphore);
+                        });
+                    }
+                } finally {
+                    concurrencySemaphore.acquireUninterruptibly(5);
+                }
+            }
+        } else {
+            Path file = Files.createFile(segmentFile);
+            try (FileChannel fc = FileChannel.open(file,
+                StandardOpenOption.READ, StandardOpenOption.WRITE)) {
+                for (int i = 0; i < loopCount; i++) {
+                    final long startPosition = 1L * blockSize * i;
+                    concurrencySemaphore.acquireUninterruptibly();
+                    CACHED_EXECUTORSERVICE.submit(() -> {
+                        writeTemplateData(fileName, fc, startPosition,
+                                blockSize, concurrencySemaphore);
+                    });
+                }
+            }
+        }
+    }
+
+    private static void writeTemplateData(String fileName,
+        FileChannel fc, long startPosition, int blockSize,
+        Semaphore concurrencySemaphore) {
+        try {
+            byte[] EMPTY_RECORD = new byte[blockSize / 256];
+
+            MappedByteBuffer mappedByteBuffer = fc.map(MapMode.READ_WRITE,
+                startPosition, blockSize);
+            IntStream.range(0, 256).forEach((recordIndex) -> {
+                try {
+                    mappedByteBuffer.position((int) (recordIndex *
+                        EMPTY_RECORD.length));
+                    mappedByteBuffer.put(EMPTY_RECORD, 0, EMPTY_RECORD.length);
+                } catch (Throwable th) {
+                    System.err.println
+                        ("Error in FileExtensionAndMap.writeTemplateData empty record for fileName: "
+                        + fileName + ", startPosition: " + startPosition + ", recordIndex: "
+                        + recordIndex + " : " + th.getMessage());
+                    th.printStackTrace(System.err);
+                }
+            });
+
+            mappedByteBuffer.force();
+        } catch (Throwable th) {
+            if (!(th instanceof ClosedChannelException)) {
+                System.err.println
+                    ("Error in FileExtensionAndMap.writeTemplateData empty record for fileName: "
+                    + fileName + ", startPosition: " + startPosition + " : "
+                    + th.getMessage());
+                th.printStackTrace(System.err);
+            }
+        } finally {
+            concurrencySemaphore.release();
+        }
+    }
+}
--- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
 public class CheckAnnotations
     extends Activatable implements MyRMI, Runnable
 {
+    private static final double TIME_FACTOR = TestLibrary.getTimeoutFactor();
 
     private static Object dummy = new Object();
     private static MyRMI myRMI = null;
@@ -111,9 +112,7 @@
             for (int i = 0; i < 3; i++) {
 
                 // object activated in annotation check via method call
-                if(!checkAnnotations(i-1)) {
-                    TestLibrary.bomb("Test failed: output improperly annotated.");
-                }
+                checkAnnotations(i-1);
 
                 /*
                  * Clean up object too.
@@ -143,24 +142,27 @@
      * check to make sure that the output from a spawned vm is
      * formatted/annotated properly.
      */
-    public static boolean checkAnnotations(int iteration)
+    public static void checkAnnotations(int iteration)
         throws IOException
     {
         try {
-            Thread.sleep(5000);
+            Thread.sleep((long)(5000 * TIME_FACTOR));
         } catch(Exception e) {
             System.err.println(e.getMessage());
         }
 
+        final String FAIL_MSG = "Test failed: output improperly annotated.";
+        final String OUT = "outABC";
+        final String ERR = "errXYZ";
         /**
          * cause the spawned vm to generate output that will
          * be checked for proper annotation.  printOut is
          * actually being called on an activated implementation.
          */
-        myRMI.printOut("out" + iteration);
-        myRMI.printErr("err" + iteration);
-        myRMI.printOut("out" + iteration);
-        myRMI.printErr("err" + iteration);
+        myRMI.printOut(OUT + iteration);
+        myRMI.printErr(ERR + iteration);
+        myRMI.printOut(OUT + iteration);
+        myRMI.printErr(ERR + iteration);
 
         /* we have to wait for output to filter down
          * from children so we can read it before we
@@ -174,7 +176,7 @@
             // have to give output from rmid time to trickle down to
             // this process
             try {
-                Thread.sleep(4000);
+                Thread.sleep((long)(4000 * TIME_FACTOR));
             } catch(InterruptedException e) {
             }
 
@@ -222,27 +224,24 @@
 
             if ((execErr == null)||(errTmp == null)||
                 (destErr == null)) {
-                return false;
+                TestLibrary.bomb(FAIL_MSG);
             }
             if ((execOut == null)||(outTmp == null)||
                 (destOut == null)) {
-                return false;
+                TestLibrary.bomb(FAIL_MSG);
             }
 
 
             // just make sure that last two strings are what we expect.
-            if (execOut.equals("ExecGroup-" + iteration)
-                && (new String(destOut.substring(0,4)).equals("out" +
+            if (!execOut.equals("ExecGroup-" + iteration)
+                || !(new String(destOut.substring(0,OUT.length()+1)).equals(OUT +
                                                               iteration))
-                && (execErr.equals("ExecGroup-"+iteration))
-                && (new String(destErr.substring(0,4)).equals("err" +
+                || !(execErr.equals("ExecGroup-"+iteration))
+                || !(new String(destErr.substring(0,ERR.length()+1)).equals(ERR +
                                                               iteration)) ) {
-                return true;
-            } else {
-                return false;
+                TestLibrary.bomb(FAIL_MSG);
             }
         }
-        return true;
     }
 
     // implementation of MyRMI, make this object activatable.
--- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,7 +140,7 @@
             System.err.println("invoking method on activatable object...");
             try {
                 obj1.ping();
-
+                throw new RuntimeException("ActivateFailedException is expected");
             } catch (ActivateFailedException e) {
 
                 /*
--- a/jdk/test/java/rmi/activation/CommandEnvironment/SetChildEnv.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/rmi/activation/CommandEnvironment/SetChildEnv.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,10 +39,14 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID ActivationLibrary RMIDSelectorProvider
  *     Eliza Retireable Doctor Doctor_Stub
- * @run main/othervm/timeout=240/policy=security.policy
- *     -Djava.compiler=NONE SetChildEnv
+ * @run main/othervm/timeout=240/policy=security.policy SetChildEnv 0 0
+ * @run main/othervm/timeout=240/policy=security.policy SetChildEnv 1 -verbosegc
+ *                       2 foo.bar=SetChildEnvTest sun.rmi.server.doSomething=true
+ * @run main/othervm/timeout=240/policy=security.policy SetChildEnv 0 1 parameter.count=zero
+ * @run main/othervm/timeout=240/policy=security.policy SetChildEnv 1 -Xmx32m 0
  */
 import java.rmi.*;
 import java.util.Properties;
@@ -55,159 +59,136 @@
 
 public class SetChildEnv
 {
-    public static void main(String argv[])
-        throws Exception
-    {
-        int runningPort = TestLibrary.getUnusedRandomPort();
-
-        System.out.println("java.compiler=" + System.getProperty("java.compiler"));
-        // don't embed spaces in any of the test args/props, because
-        // they won't be parsed properly
-        runwith (new String[0], new String[0], runningPort);
+    public static void main(String argv[]) throws Exception {
+        RMID rmid = null;
+        try {
+            System.out.println("java.compiler=" + System.getProperty("java.compiler"));
+            int paramCount = Integer.valueOf(argv[0]);
+            String[] params = paramCount == 0 ?
+                    new String[0] : Arrays.copyOfRange(argv, 1, paramCount+1);
+            int propCount = Integer.valueOf(argv[paramCount+1]);
+            String[] props = propCount == 0 ?
+                    new String[0] :
+                    Arrays.copyOfRange(argv, paramCount+2, paramCount+propCount+2);
 
-        runwith (
-            new String[] { "-verbosegc" },
-            new String[] { "foo.bar=SetChildEnvTest",
-                           "sun.rmi.server.doSomething=true" },
-            runningPort
-            );
+            TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager);
+
+            // make a "watcher" which listens on a pipe and searches for
+            // the debugExec line while teeing to System.err
+            DebugExecWatcher watcher = DebugExecWatcher.makeWithPipe();
 
-        runwith (
-            new String[] { },
-            new String[] { "parameter.count=zero" },
-            runningPort
-            );
+            RMID.removeLog();
+            rmid = RMID.createRMIDOnEphemeralPort(watcher.otherEnd(),
+                                                  watcher.otherEnd(), true);
+
+            rmid.start();
 
-        runwith (
-            new String[] { "-Xmx32m" },
-            new String[] { },
-            runningPort
-            );
-    }
+            // compile props
+            Properties p = new Properties();
+            p.put("java.security.policy", TestParams.defaultGroupPolicy);
+            p.put("java.security.manager", TestParams.defaultSecurityManager);
+            //p.put("java.rmi.server.logCalls", "true");
+            int i;
+            for (i = 0; i < props.length; i++) {
+                p.put(props[i].substring(0, props[i].indexOf('=')),
+                      props[i].substring(props[i].indexOf('=')+1));
+            }
+
+            // create CommandEnvironment and ActivationGroupDesc
+            ActivationGroupDesc.CommandEnvironment cmdenv =
+                    new ActivationGroupDesc.CommandEnvironment(
+                        null,
+                        params);
 
-    private static void runwith(
-        String[] params,        // extra args
-        String[] props,         // extra system properties
-        int port                // port on which to communicate
-    )
-        throws Exception
-    {
-        TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager);
+            ActivationGroupDesc gdesc = new ActivationGroupDesc(
+                    p, cmdenv);
+
+            // register group
+            ActivationSystem actsys = ActivationGroup.getSystem();
+            ActivationGroupID gid = actsys.registerGroup(gdesc);
 
-        // make a "watcher" which listens on a pipe and searches for
-        // the debugExec line while teeing to System.err
-        DebugExecWatcher watcher = DebugExecWatcher.makeWithPipe();
+            // create ActivationDesc
+            ActivationDesc odesc = new ActivationDesc(gid, // group
+                                                      "Doctor", // class
+                                                      null, // codesource
+                                                      null); // closure data
 
-        RMID.removeLog();
-        RMID rmid = RMID.createRMID(watcher.otherEnd(), watcher.otherEnd(),
-                                    true,  // debugExec turned on
-                                    true, port);
+            // register activatable object
+            Eliza doctor = (Eliza)Activatable.register(odesc);
 
-        rmid.start();
+            // invoke a call with oh-so-humorous sample text
+            System.out.println ("Invoking complain()...");
+            String complaint =
+                    "HELP ME, DOCTOR.  I FEEL VIOLENT TOWARDS PEOPLE " +
+                    "WHO INQUIRE ABOUT MY PARENTS.";
 
-        // compile props
-        Properties p = new Properties();
-        p.put("java.security.policy", TestParams.defaultGroupPolicy);
-        p.put("java.security.manager", TestParams.defaultSecurityManager);
-        //p.put("java.rmi.server.logCalls", "true");
-        int i;
-        for (i = 0; i < props.length; i++) {
-            p.put(props[i].substring(0, props[i].indexOf('=')),
-                  props[i].substring(props[i].indexOf('=')+1));
-        }
+            System.out.println(complaint);
+            //Runtime.getRuntime().traceMethodCalls(true);
+            String res = doctor.complain(complaint);
+            //Runtime.getRuntime().traceMethodCalls(false);
+            System.out.println (" => " + res);
 
-        // create CommandEnvironment and ActivationGroupDesc
-        ActivationGroupDesc.CommandEnvironment cmdenv =
-                new ActivationGroupDesc.CommandEnvironment(
-                    null,
-                    params);
+            // Get debugExec line, allowing 15 seconds for it to flush
+            // through the buffers and pipes.
+            String found = watcher.found;
+            if (found == null) {
+                int fudge = 15;
+                while (found == null && --fudge > 0) {
+                    Thread.sleep(1000);
+                    found = watcher.found;
+                }
+                if (found == null) {
+                    TestLibrary.bomb("rmid subprocess produced no " +
+                                     "recognizable debugExec line");
+                }
+            }
 
-        ActivationGroupDesc gdesc = new ActivationGroupDesc(
-                p, cmdenv);
-
-        // register group
-        ActivationSystem actsys = ActivationGroup.getSystem();
-        ActivationGroupID gid = actsys.registerGroup(gdesc);
+            System.err.println("debugExec found: <<" + found + ">>");
+            // q: first double-quote after debugExec
+            int q = found.indexOf('"', found.indexOf("rmid: debugExec"));
+            // qe: last double-quote on debugExec line
+            int qe = found.lastIndexOf('"');
+            if (q <= 1 || qe <= q) {
+                TestLibrary.bomb("rmid subprocess produced " +
+                                 "mangled debugExec line");
+            }
 
-        // create ActivationDesc
-        ActivationDesc odesc = new ActivationDesc(gid, // group
-                                                  "Doctor", // class
-                                                  null, // codesource
-                                                  null); // closure data
+            // split args by whitespace
+            StringTokenizer tk = new StringTokenizer(found.substring(q+1, qe));
+            tk.nextToken();         // skip command path/name
 
-        // register activatable object
-        Eliza doctor = (Eliza)Activatable.register(odesc);
+            // Now check off the requested args.  Order isn't important, and
+            // any extra args are ignored, even if they're inconsistent or
+            // bargage, or duplicates.
 
-        // invoke a call with oh-so-humorous sample text
-        System.out.println ("Invoking complain()...");
-        String complaint =
-                "HELP ME, DOCTOR.  I FEEL VIOLENT TOWARDS PEOPLE " +
-                "WHO INQUIRE ABOUT MY PARENTS.";
+            Set argset = new HashSet(tk.countTokens());
+            while (tk.hasMoreTokens()) {
+                argset.add(tk.nextToken());
+            }
 
-        System.out.println(complaint);
-        //Runtime.getRuntime().traceMethodCalls(true);
-        String res = doctor.complain(complaint);
-        //Runtime.getRuntime().traceMethodCalls(false);
-        System.out.println (" => " + res);
+            int m;
+            for (m = 0; m < params.length; m++) {
+                if(!argset.contains(params[m]))
+                    TestLibrary.bomb("Parameter \"" + params[m] + "\" not set");
+            }
 
-        // Get debugExec line, allowing 15 seconds for it to flush
-        // through the buffers and pipes.
-        String found = watcher.found;
-        if (found == null) {
-            int fudge = 15;
-            while (found == null && --fudge > 0) {
-                Thread.sleep(1000);
-                found = watcher.found;
+            for (m = 0; m < props.length; m++) {
+                if (!argset.contains("-D" + props[m])) {
+                    TestLibrary.bomb("Property binding \"" + props[m] +
+                                     "\" not set");
+                }
             }
-            if (found == null) {
-                TestLibrary.bomb("rmid subprocess produced no " +
-                                 "recognizable debugExec line");
+
+            // End doctor
+            if (doctor instanceof Retireable)
+                ((Retireable)doctor).retire();
+            actsys.unregisterGroup(gid);
+        } finally {
+            Thread.sleep(5000);
+            if (rmid != null) {
+                rmid.cleanup();
             }
         }
-
-        System.err.println("debugExec found: <<" + found + ">>");
-        // q: first double-quote after debugExec
-        int q = found.indexOf('"', found.indexOf("rmid: debugExec"));
-        // qe: last double-quote on debugExec line
-        int qe = found.lastIndexOf('"');
-        if (q <= 1 || qe <= q) {
-            TestLibrary.bomb("rmid subprocess produced " +
-                             "mangled debugExec line");
-        }
-
-        // split args by whitespace
-        StringTokenizer tk = new StringTokenizer(found.substring(q+1, qe));
-        tk.nextToken();         // skip command path/name
-
-        // Now check off the requested args.  Order isn't important, and
-        // any extra args are ignored, even if they're inconsistent or
-        // bargage, or duplicates.
-
-        Set argset = new HashSet(tk.countTokens());
-        while (tk.hasMoreTokens()) {
-            argset.add(tk.nextToken());
-        }
-
-        int m;
-        for (m = 0; m < params.length; m++) {
-            if(!argset.contains(params[m]))
-                TestLibrary.bomb("Parameter \"" + params[m] + "\" not set");
-        }
-
-        for (m = 0; m < props.length; m++) {
-            if (!argset.contains("-D" + props[m])) {
-                TestLibrary.bomb("Property binding \"" + props[m] +
-                                 "\" not set");
-            }
-        }
-
-        // End doctor
-        if (doctor instanceof Retireable)
-            ((Retireable)doctor).retire();
-        actsys.unregisterGroup(gid);
-
-        Thread.sleep(5000);
-        rmid.cleanup();
     }
 
     public static class DebugExecWatcher
@@ -272,75 +253,3 @@
         }
     }
 }
-
-/*
-   code graveyard
-
-        // activation should have proceeded by writing a wrapper.out
-        // when test.src/actgrpwrapper was run.
-
-        // Read and check wrapper.out
-        BufferedReader r = new BufferedReader(new FileReader(wrapout));
-        String[] realArgs = null;
-        String line;
-
-        while ( (line = r.readLine()) != null) {
-            StringTokenizer tkz = new StringTokenizer(line);
-            if (!tkz.nextToken().equals("actgrpwrapper")) {
-                // could throw an exception, but let's benignly
-                // assume that something unrelated is spewing.
-                continue;
-            }
-            String x;   // writer's block
-            x = tkz.nextToken();
-            if (x.equals("argc")) {
-                if (realArgs != null) {
-                    throw new RuntimeException(
-                            "SetChildEnv: two argc lines in wrapper.out");
-                }
-                realArgs = new String[Integer.parseInt(tkz.nextToken())];
-            } else if (x.equals("argv")) {
-                if (realArgs == null)
-                    throw new RuntimeException("SetChildEnv: missing argc");
-                int n = Integer.parseInt(tkz.nextToken());
-                if (n < 1 || n > realArgs.length) {
-                    throw new RuntimeException("SetChildEnv: argc=" +
-                            realArgs.length + "; argv[" + n + "]");
-                }
-                // Hack: manually skip the "actgrpwrapper argv 5 "
-                String remainder = line.substring(
-                        1 + line.indexOf(' ',
-                                1 + line.indexOf(' ',
-                                        1 + line.indexOf(' '))));
-                realArgs[n-1] = remainder;
-            } else {
-                throw new RuntimeException("SetChildEnv: bad token \"" + x + "\"");
-            }
-        }
-        r.close();
-
-    private static void ensureLocalExecutable(String fname)
-        throws Exception
-    {
-        File target = new File(fname);
-        File source = new File(Dot, fname);
-        if (!target.exists()) {
-            // copy from source
-            System.err.println("Copying " + source.getPath() +
-                               " to " + target.getPath());
-            java.io.InputStream in = new java.io.FileInputStream(source);
-            java.io.OutputStream out = new java.io.FileOutputStream(target);
-            byte[] buf = new byte[512];
-            int n;
-            while ((n = in.read(buf, 0, 512)) > 0) {
-                out.write(buf, 0, n);
-            }
-            out.close();
-            in.close();
-        }
-        // chmod
-        System.err.println("Doing: /bin/chmod 755 " + fname);
-        Runtime.getRuntime().exec("/bin/chmod 755 " + fname).waitFor();
-    }
-
-*/
--- a/jdk/test/java/rmi/activation/CommandEnvironment/rmid.security.policy	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/rmi/activation/CommandEnvironment/rmid.security.policy	Tue Dec 13 02:04:23 2016 +0100
@@ -6,4 +6,9 @@
     permission com.sun.rmi.rmid.ExecOptionPermission "-verbosegc";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Dparameter.count=zero";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Xmx32m";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
+    permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.port", "read";
+    permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.timeout", "read";
+    permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
 };
--- a/jdk/test/java/util/Collections/SingletonIterator.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/util/Collections/SingletonIterator.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8024500 8166446
  * @run testng SingletonIterator
  */
 
@@ -38,6 +39,15 @@
 
 @Test(groups = "unit")
 public class SingletonIterator {
+    static void assertIteratorExhausted(Iterator<?> it) {
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            fail("should have thrown NoSuchElementException");
+        } catch (NoSuchElementException success) { }
+        it.forEachRemaining(e -> { throw new AssertionError("action called incorrectly"); });
+    }
+
     public void testForEachRemaining() {
         Iterator<String> it = Collections.singleton("TheOne").iterator();
         AtomicInteger cnt = new AtomicInteger(0);
@@ -48,13 +58,18 @@
         });
 
         assertEquals(cnt.get(), 1);
-        assertFalse(it.hasNext());
+        assertIteratorExhausted(it);
+    }
+
+    static class SingletonException extends RuntimeException { }
+
+    public void testThrowFromForEachRemaining() {
+        Iterator<String> it = Collections.singleton("TheOne").iterator();
 
         try {
-            String str = it.next();
-            fail("Should throw NoSuchElementException at end");
-        } catch (NoSuchElementException ex) {
-            // ignore;
-        }
+            it.forEachRemaining(s -> { throw new SingletonException(); });
+        } catch (SingletonException ignore) { }
+
+        assertIteratorExhausted(it);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Locale/Bug8071929.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,149 @@
+/*
+ * 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 8071929
+ * @summary Test obsolete ISO3166-1 alpha-2 country codes should not be retrieved.
+ * ISO3166-1 alpha-2, ISO3166-1 alpha-3, ISO3166-3 country codes
+ * from overloaded getISOCountries(Iso3166 type) are retrieved correctly.
+ */
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Locale.IsoCountryCode;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class Bug8071929 {
+
+    private static final List<String> ISO3166_1_ALPHA2_OBSOLETE_CODES = List.of("AN", "BU", "CS",
+            "NT", "SF", "TP", "YU", "ZR");
+
+    private static final Set<String> ISO3166_3EXPECTED = Set.of(
+            "AIDJ", "ANHH", "BQAQ", "BUMM", "BYAA", "CSHH", "CSXX", "CTKI", "DDDE",
+            "DYBJ", "FQHH", "FXFR", "GEHH", "HVBF", "JTUM", "MIUM", "NHVU", "NQAQ",
+            "NTHH", "PCHH", "PUUM", "PZPA", "RHZW", "SKIN", "SUHH", "TPTL", "VDVN",
+            "WKUM", "YDYE", "YUCS", "ZRCD");
+
+    private static final Set<String> ISO3166_1_ALPHA3_EXPECTED
+            = Set.of("ABW", "AFG", "AGO", "AIA", "ALA", "ALB", "AND",
+                    "ARE", "ARG", "ARM", "ASM", "ATA", "ATF", "ATG",
+                    "AUS", "AUT", "AZE", "BDI", "BEL", "BEN", "BES", "BFA",
+                    "BGD", "BGR", "BHR", "BHS", "BIH", "BLM", "BLR", "BLZ",
+                    "BMU", "BOL", "BRA", "BRB", "BRN", "BTN", "BVT", "BWA", "CAF", "CAN",
+                    "CCK", "CHE", "CHL", "CHN", "CIV", "CMR", "COD", "COG", "COK", "COL",
+                    "COM", "CPV", "CRI", "CUB", "CUW", "CXR", "CYM", "CYP", "CZE", "DEU",
+                    "DJI", "DMA", "DNK", "DOM", "DZA", "ECU", "EGY", "ERI", "ESH", "ESP",
+                    "EST", "ETH", "FIN", "FJI", "FLK", "FRA", "FRO", "FSM", "GAB", "GBR",
+                    "GEO", "GGY", "GHA", "GIB", "GIN", "GLP", "GMB", "GNB", "GNQ",
+                    "GRC", "GRD", "GRL", "GTM", "GUF", "GUM", "GUY", "HKG", "HMD", "HND",
+                    "HRV", "HTI", "HUN", "IDN", "IMN", "IND", "IOT", "IRL", "IRN", "IRQ",
+                    "ISL", "ISR", "ITA", "JAM", "JEY", "JOR", "JPN", "KAZ", "KEN", "KGZ",
+                    "KHM", "KIR", "KNA", "KOR", "KWT", "LAO", "LBN", "LBR", "LBY", "LCA",
+                    "LIE", "LKA", "LSO", "LTU", "LUX", "LVA", "MAC", "MAF", "MAR", "MCO",
+                    "MDA", "MDG", "MDV", "MEX", "MHL", "MKD", "MLI", "MLT", "MMR", "MNE",
+                    "MNG", "MNP", "MOZ", "MRT", "MSR", "MTQ", "MUS", "MWI", "MYS", "MYT",
+                    "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NIU", "NLD", "NOR", "NPL",
+                    "NRU", "NZL", "OMN", "PAK", "PAN", "PCN", "PER", "PHL", "PLW", "PNG",
+                    "POL", "PRI", "PRK", "PRT", "PRY", "PSE", "PYF", "QAT", "REU", "ROU",
+                    "RUS", "RWA", "SAU", "SDN", "SEN", "SGP", "SGS", "SHN", "SJM", "SLB",
+                    "SLE", "SLV", "SMR", "SOM", "SPM", "SRB", "SSD", "STP", "SUR", "SVK",
+                    "SVN", "SWE", "SWZ", "SXM", "SYC", "SYR", "TCA", "TCD", "TGO", "THA",
+                    "TJK", "TKL", "TKM", "TLS", "TON", "TTO", "TUN", "TUR", "TUV", "TWN",
+                    "TZA", "UGA", "UKR", "UMI", "URY", "USA", "UZB", "VAT", "VCT", "VEN",
+                    "VGB", "VIR", "VNM", "VUT", "WLF", "WSM", "YEM", "ZAF", "ZMB", "ZWE");
+
+    /**
+     * This method checks that obsolete ISO3166-1 alpha-2 country codes are not
+     * retrieved in output of getISOCountries() method.
+     */
+    private static void checkISO3166_1_Alpha2ObsoleteCodes() {
+        Set<String> unexpectedCodes = ISO3166_1_ALPHA2_OBSOLETE_CODES.stream().
+                filter(Set.of(Locale.getISOCountries())::contains).collect(Collectors.toSet());
+        if (!unexpectedCodes.isEmpty()) {
+            throw new RuntimeException("Obsolete ISO3166-1 alpha2 two letter"
+                    + " country Codes " + unexpectedCodes + " in output of getISOCountries() method");
+        }
+    }
+
+    /**
+     * This method checks that ISO3166-3 country codes which are PART3 of
+     * IsoCountryCode enum, are retrieved correctly.
+     */
+    private static void checkISO3166_3Codes() {
+        Set<String> iso3166_3Codes = Locale.getISOCountries(IsoCountryCode.PART3);
+        if (!iso3166_3Codes.equals(ISO3166_3EXPECTED)) {
+            reportDifference(iso3166_3Codes, ISO3166_3EXPECTED);
+        }
+    }
+
+    /**
+     * This method checks that ISO3166-1 alpha-3 country codes which are
+     * PART1_ALPHA3 of IsoCountryCode enum, are retrieved correctly.
+     */
+    private static void checkISO3166_1_Alpha3Codes() {
+        Set<String> iso3166_1_Alpha3Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA3);
+        if (!iso3166_1_Alpha3Codes.equals(ISO3166_1_ALPHA3_EXPECTED)) {
+            reportDifference(iso3166_1_Alpha3Codes, ISO3166_1_ALPHA3_EXPECTED);
+        }
+    }
+
+    /**
+     * This method checks that ISO3166-1 alpha-2 country codes, which are
+     * PART1_ALPHA2 of IsoCountryCode enum, are retrieved correctly.
+     */
+    private static void checkISO3166_1_Alpha2Codes() {
+        Set<String> iso3166_1_Alpha2Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA2);
+        Set<String> ISO3166_1_ALPHA2_EXPECTED = Set.of(Locale.getISOCountries());
+        if (!iso3166_1_Alpha2Codes.equals(ISO3166_1_ALPHA2_EXPECTED)) {
+            reportDifference(iso3166_1_Alpha2Codes, ISO3166_1_ALPHA2_EXPECTED);
+        }
+    }
+
+    private static void reportDifference(Set<String> retrievedCountrySet, Set<String> expectedCountrySet) {
+        Set<String> retrievedSet = new HashSet<>(retrievedCountrySet);
+        Set<String> expectedSet = new HashSet<>(expectedCountrySet);
+        retrievedSet.removeAll(expectedCountrySet);
+        expectedSet.removeAll(retrievedCountrySet);
+        if ((retrievedSet.size() > 0) && (expectedSet.size() > 0)) {
+            throw new RuntimeException("Retrieved country codes set contains extra codes "
+                    + retrievedSet + " and missing codes " + expectedSet);
+        }
+        if (retrievedSet.size() > 0) {
+            throw new RuntimeException("Retrieved country codes set contains extra codes "
+                    + retrievedSet);
+        }
+        if (expectedSet.size() > 0) {
+            throw new RuntimeException("Retrieved country codes set is missing codes "
+                    + expectedSet);
+        }
+    }
+
+    public static void main(String[] args) {
+        checkISO3166_1_Alpha2ObsoleteCodes();
+        checkISO3166_1_Alpha2Codes();
+        checkISO3166_1_Alpha3Codes();
+        checkISO3166_3Codes();
+    }
+}
--- a/jdk/test/java/util/Locale/LocaleTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/util/Locale/LocaleTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -25,7 +25,7 @@
  * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613
  * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951
  * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549
- * 6786276 7066203 7085757 8008577 8030696
+ * 6786276 7066203 7085757 8008577 8030696 8170840
  * @summary test Locales
  * @library /java/text/testlib
  * @modules jdk.localedata
@@ -489,8 +489,8 @@
         String[] spotCheck2 = {"US", "CA", "GB", "FR", "DE", "IT", "JP", "KR", "CN", "TW", "TH"};
 
 
-        if (test.length != 250) {
-            errln("Expected getISOCountries to return 250 countries; it returned " + test.length);
+        if (test.length != 249) {
+            errln("Expected getISOCountries to return 249 countries; it returned " + test.length);
         } else {
             for (int i = 0; i < spotCheck2.length; i++) {
                 int j;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/CacheTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8170772
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * @build CacheTest CompilerUtils jdk.testlibrary.*
+ * @run testng CacheTest
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.testlibrary.OutputAnalyzer;
+import static jdk.testlibrary.ProcessTools.*;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+
+@Test
+public class CacheTest {
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MODS_DIR = Paths.get("mods");
+
+    private static final String TEST_MODULE = "test";
+    private static final String MAIN_BUNDLES_MODULE = "mainbundles";
+
+    private static final String MAIN = "test/jdk.test.Main";
+    private static final String MAIN_CLASS = "jdk.test.Main";
+
+    @BeforeTest
+    public void compileTestModules() throws Exception {
+
+        for (String mn : new String[] {MAIN_BUNDLES_MODULE, TEST_MODULE}) {
+            boolean compiled =
+                CompilerUtils.compile(SRC_DIR.resolve(mn),
+                                      MODS_DIR.resolve(mn),
+                            "--module-path", MODS_DIR.toString());
+            assertTrue(compiled, "module " + mn + " did not compile");
+        }
+
+        Path res = Paths.get("jdk", "test", "resources", "MyResources.properties");
+        Path dest = MODS_DIR.resolve(MAIN_BUNDLES_MODULE).resolve(res);
+        Files.createDirectories(dest.getParent());
+        Files.copy(SRC_DIR.resolve(MAIN_BUNDLES_MODULE).resolve(res), dest);
+    }
+
+    /**
+     * Load resource bundle in cache first.  Verify that the subsequent
+     * loading of ResourceBundle from another module will not get it from cache.
+     */
+    @Test
+    public void loadCacheFirst() throws Exception {
+        assertTrue(executeTestJava("--module-path", MODS_DIR.toString(),
+                                   "-m", MAIN, "cache")
+                        .outputTo(System.out)
+                        .errorTo(System.out)
+                        .getExitValue() == 0);
+
+        assertTrue(executeTestJava("--class-path", MODS_DIR.resolve(TEST_MODULE).toString(),
+                                   "--module-path", MODS_DIR.resolve(MAIN_BUNDLES_MODULE).toString(),
+                                   "--add-modules", MAIN_BUNDLES_MODULE,
+                                   MAIN_CLASS, "cache")
+                        .outputTo(System.out)
+                        .errorTo(System.out)
+                        .getExitValue() == 0);
+    }
+
+    /**
+     * Load non-existent resource bundle in cache first.  Verify that
+     * the subsequent loading of ResourceBundle from another module
+     * can still successfully load the bundle.
+     */
+    @Test
+    public void loadNonExistentBundleInCache() throws Exception {
+        assertTrue(executeTestJava("--module-path", MODS_DIR.toString(),
+                                   "-m", MAIN)
+                        .outputTo(System.out)
+                        .errorTo(System.out)
+                        .getExitValue() == 0);
+
+        assertTrue(executeTestJava("--class-path", MODS_DIR.resolve(TEST_MODULE).toString(),
+                                   "--module-path", MODS_DIR.resolve(MAIN_BUNDLES_MODULE).toString(),
+                                   "--add-modules", MAIN_BUNDLES_MODULE,
+                                   MAIN_CLASS)
+                        .outputTo(System.out)
+                        .errorTo(System.out)
+                        .getExitValue() == 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/src/mainbundles/jdk/test/resources/MyResources.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+key=root: message
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/src/mainbundles/jdk/test/util/Bundles.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.util;
+
+import java.util.ResourceBundle;
+
+public class Bundles {
+    static final String MAIN_BUNDLES_RESOURCE = "jdk.test.resources.MyResources";
+
+    public static ResourceBundle getBundle() {
+        return ResourceBundle.getBundle(MAIN_BUNDLES_RESOURCE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/src/mainbundles/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module mainbundles {
+    exports jdk.test.util;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/src/test/jdk/test/Main.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test;
+
+import java.lang.reflect.Module;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Main {
+    static final String MAIN_BUNDLES_RESOURCE = "jdk.test.resources.MyResources";
+    public static void main(String[] args) {
+        if (args.length == 1 && args[0].equals("cache")) {
+            // first load resource bundle in the cache
+            jdk.test.util.Bundles.getBundle();
+
+            // fail to load resource bundle that is present in the cache
+            try {
+                Module mainbundles = jdk.test.util.Bundles.class.getModule();
+                ResourceBundle rb = ResourceBundle.getBundle(MAIN_BUNDLES_RESOURCE, mainbundles);
+                throw new RuntimeException("ERROR: test module loads " + rb);
+            } catch (MissingResourceException e) {
+                System.out.println("Expected: " + e.getMessage());
+            }
+        } else {
+            // fail to load resource bundle; NON_EXISTENT_BUNDLE in the cache
+            try {
+                Module mainbundles = jdk.test.util.Bundles.class.getModule();
+                ResourceBundle rb = ResourceBundle.getBundle(MAIN_BUNDLES_RESOURCE, mainbundles);
+                throw new RuntimeException("ERROR: test module loads " + rb);
+            } catch (MissingResourceException e) {
+                System.out.println("Expected: " + e.getMessage());
+            }
+
+            // successfully load the resource bundle
+            jdk.test.util.Bundles.getBundle();
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/src/test/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module test {
+    requires mainbundles;
+}
--- a/jdk/test/java/util/ResourceBundle/modules/security/src/m1/module-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/util/ResourceBundle/modules/security/src/m1/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,4 +23,5 @@
 
 module m1 {
     exports p1;
+    opens p1.resources to test;
 }
--- a/jdk/test/java/util/ResourceBundle/modules/security/src/test/jdk/test/Main.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/util/ResourceBundle/modules/security/src/test/jdk/test/Main.java	Tue Dec 13 02:04:23 2016 +0100
@@ -39,9 +39,11 @@
 
         // resource in another module
         Module m1 = p1.Bundle.class.getModule();
+
+        // bundles loaded with different cache key
         ResourceBundle rb1 = Bundle.getBundle(M1_RESOURCE_BUNDLE_NAME);
         ResourceBundle rb2 = ResourceBundle.getBundle(M1_RESOURCE_BUNDLE_NAME, m1);
-        if (rb1 != rb2) {
+        if (rb1 == rb2) {
             throw new RuntimeException("unexpected resource bundle");
         }
 
--- a/jdk/test/java/util/zip/ZipFile/TestZipFile.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/java/util/zip/ZipFile/TestZipFile.java	Tue Dec 13 02:04:23 2016 +0100
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 8142508 8146431
+ * @modules java.base/java.util.zip:open
  * @summary Tests various ZipFile apis
  * @run main/manual TestZipFile
  */
--- a/jdk/test/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,12 +43,12 @@
 public class RMIConnector_NPETest {
     public static void main(String argv[]) throws Exception {
         RMID rmid = RMID.createRMID();
-        rmid.start();
-        int rmidPort = rmid.getPort();
         Exception failureCause = null;
         RMIConnector agent = null;
 
         try {
+            rmid.start();
+            int rmidPort = rmid.getPort();
             MBeanServer mbs = MBeanServerFactory.createMBeanServer();
             RMIJRMPServerImpl rmiserver = new RMIJRMPServerImpl(rmidPort, null, null, null);
             rmiserver.setMBeanServer(mbs);
@@ -75,3 +75,4 @@
 
     }
 }
+
--- a/jdk/test/javax/net/ssl/DTLS/CipherSuite.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/javax/net/ssl/DTLS/CipherSuite.java	Tue Dec 13 02:04:23 2016 +0100
@@ -27,7 +27,6 @@
 /*
  * @test
  * @bug 8043758
- * @key intermittent
  * @summary Datagram Transport Layer Security (DTLS)
  * @modules java.base/sun.security.util
  *          jdk.crypto.ec
--- a/jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,425 +21,215 @@
  * questions.
  */
 
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.SocketTimeoutException;
-import java.security.KeyStore;
-import java.security.Security;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * This class defines a framework for JSSE tests.
- *
- * Please run in othervm mode.  SunJSSE does not support dynamic system
- * properties, no way to re-use system properties in samevm/agentvm mode.
- */
+//
+// Please run in othervm mode.  SunJSSE does not support dynamic system
+// properties, no way to re-use system properties in samevm/agentvm mode.
+//
 
 /*
  * @test
- * @bug 1234567
- * @summary Use this class for JSSE tests
+ * @bug 8161106 8170329
+ * @summary Improve SSLSocket test template
  * @run main/othervm SSLSocketTemplate
- * @author Brad Wetmore
  */
+import java.io.*;
+import javax.net.ssl.*;
+import java.net.InetSocketAddress;
+import java.net.SocketTimeoutException;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.KeyFactory;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.*;
+import java.util.Base64;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Template to help speed your client/server tests.
+ *
+ * Two examples that use this template:
+ *    test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java
+ *    test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java
+ */
 public class SSLSocketTemplate {
 
-    public static final String TEST_SRC = System.getProperty("test.src", ".");
+    /*
+     * ==================
+     * Run the test case.
+     */
+    public static void main(String[] args) throws Exception {
+        (new SSLSocketTemplate()).run();
+    }
+
+    /*
+     * Run the test case.
+     */
+    public void run() throws Exception {
+        bootup();
+    }
+
+    /*
+     * Define the server side application of the test for the specified socket.
+     */
+    protected void runServerApplication(SSLSocket socket) throws Exception {
+        // here comes the test logic
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
+
+        sslIS.read();
+        sslOS.write(85);
+        sslOS.flush();
+    }
+
+    /*
+     * Define the client side application of the test for the specified socket.
+     * This method is used if the returned value of
+     * isCustomizedClientConnection() is false.
+     *
+     * @param socket may be null is no client socket is generated.
+     *
+     * @see #isCustomizedClientConnection()
+     */
+    protected void runClientApplication(SSLSocket socket) throws Exception {
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
+
+        sslOS.write(280);
+        sslOS.flush();
+        sslIS.read();
+    }
 
     /*
-     * Where do we find the keystores?
+     * Define the client side application of the test for the specified
+     * server port.  This method is used if the returned value of
+     * isCustomizedClientConnection() is true.
+     *
+     * Note that the client need to connect to the server port by itself
+     * for the actual message exchange.
+     *
+     * @see #isCustomizedClientConnection()
      */
-    public static final String PATH_TO_STORES = "../etc";
-    public static final String KEY_STORE_FILE = "keystore";
-    public static final String TRUST_STORE_FILE = "truststore";
-    public static final String PASSWORD = "passphrase";
+    protected void runClientApplication(int serverPort) throws Exception {
+        // blank
+    }
 
-    public static final int FREE_PORT = 0;
+    /*
+     * Create an instance of SSLContext for client use.
+     */
+    protected SSLContext createClientSSLContext() throws Exception {
+        return createSSLContext(trustedCertStrs,
+                endEntityCertStrs, endEntityPrivateKeys,
+                endEntityPrivateKeyNames,
+                getClientContextParameters());
+    }
 
-    // in seconds
-    public static final long CLIENT_SIGNAL_TIMEOUT = 30L;
-    public static final long SERVER_SIGNAL_TIMEOUT = 90L;
-
-    // in millis
-    public static final int CLIENT_TIMEOUT = 15000;
-    public static final int SERVER_TIMEOUT = 30000;
+    /*
+     * Create an instance of SSLContext for server use.
+     */
+    protected SSLContext createServerSSLContext() throws Exception {
+        return createSSLContext(trustedCertStrs,
+                endEntityCertStrs, endEntityPrivateKeys,
+                endEntityPrivateKeyNames,
+                getServerContextParameters());
+    }
 
     /*
-     * Should we run the client or server in a separate thread?
-     * Both sides can throw exceptions, but do you have a preference
-     * as to which side should be the main thread.
+     * The parameters used to configure SSLContext.
      */
-    private boolean separateServerThread = false;
+    protected static final class ContextParameters {
+        final String contextProtocol;
+        final String tmAlgorithm;
+        final String kmAlgorithm;
+
+        ContextParameters(String contextProtocol,
+                String tmAlgorithm, String kmAlgorithm) {
+
+            this.contextProtocol = contextProtocol;
+            this.tmAlgorithm = tmAlgorithm;
+            this.kmAlgorithm = kmAlgorithm;
+        }
+    }
+
+    /*
+     * Get the client side parameters of SSLContext.
+     */
+    protected ContextParameters getClientContextParameters() {
+        return new ContextParameters("TLS", "PKIX", "NewSunX509");
+    }
 
     /*
-     * What's the server port?  Use any free port by default
+     * Get the server side parameters of SSLContext.
      */
-    private volatile int serverPort;
-
-    private volatile Exception serverException;
-    private volatile Exception clientException;
+    protected ContextParameters getServerContextParameters() {
+        return new ContextParameters("TLS", "PKIX", "NewSunX509");
+    }
 
-    private Thread clientThread;
-    private Thread serverThread;
+    /*
+     * Does the client side use customized connection other than
+     * explicit Socket.connect(), for example, URL.openConnection()?
+     */
+    protected boolean isCustomizedClientConnection() {
+        return false;
+    }
 
-    private Peer serverPeer;
-    private Peer clientPeer;
-
-    private Application serverApplication;
-    private Application clientApplication;
-
-    private SSLContext context;
+    /*
+     * =============================================
+     * Define the client and server side operations.
+     *
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
 
     /*
      * Is the server ready to serve?
      */
-    private final CountDownLatch serverReadyCondition = new CountDownLatch(1);
+    private final CountDownLatch serverCondition = new CountDownLatch(1);
 
     /*
      * Is the client ready to handshake?
      */
-    private final CountDownLatch clientReadyCondition = new CountDownLatch(1);
-
-    /*
-     * Is the server done?
-     */
-    private final CountDownLatch serverDoneCondition = new CountDownLatch(1);
-
-    /*
-     * Is the client done?
-     */
-    private final CountDownLatch clientDoneCondition = new CountDownLatch(1);
+    private final CountDownLatch clientCondition = new CountDownLatch(1);
 
     /*
-     * Public API.
+     * What's the server port?  Use any free port by default
      */
-
-    public static interface Peer {
-        void run(SSLSocketTemplate test) throws Exception;
-    }
-
-    public static interface Application {
-        void run(SSLSocket socket, SSLSocketTemplate test) throws Exception;
-    }
-
-    public static void debug() {
-        debug("ssl");
-    }
-
-    public static void debug(String mode) {
-        System.setProperty("javax.net.debug", mode);
-    }
-
-    public static void setup(String keyFilename, String trustFilename,
-            String password) {
-
-        System.setProperty("javax.net.ssl.keyStore", keyFilename);
-        System.setProperty("javax.net.ssl.keyStorePassword", password);
-        System.setProperty("javax.net.ssl.trustStore", trustFilename);
-        System.setProperty("javax.net.ssl.trustStorePassword", password);
-    }
-
-    public static void setup() throws Exception {
-        String keyFilename = TEST_SRC + "/" + PATH_TO_STORES + "/"
-                + KEY_STORE_FILE;
-        String trustFilename = TEST_SRC + "/" + PATH_TO_STORES + "/"
-                + TRUST_STORE_FILE;
-
-        setup(keyFilename, trustFilename, PASSWORD);
-    }
-
-    public static void print(String message, Throwable... errors) {
-        synchronized (System.out) {
-            System.out.println(message);
-            for (Throwable e : errors) {
-                e.printStackTrace(System.out);
-            }
-        }
-    }
-
-    public static KeyStore loadJksKeyStore(String filename, String password)
-            throws Exception {
-
-        return loadKeyStore(filename, password, "JKS");
-    }
-
-    public static KeyStore loadKeyStore(String filename, String password,
-            String type) throws Exception {
-
-        KeyStore keystore = KeyStore.getInstance(type);
-        FileInputStream fis = new FileInputStream(filename);
-        try {
-            keystore.load(fis, password.toCharArray());
-        } finally {
-            fis.close();
-        }
-        return keystore;
-    }
-
-    // Try to accept a connection in 30 seconds.
-    public static SSLSocket accept(SSLServerSocket sslServerSocket)
-            throws IOException {
-
-        return accept(sslServerSocket, SERVER_TIMEOUT);
-    }
-
-    public static SSLSocket accept(SSLServerSocket sslServerSocket, int timeout)
-            throws IOException {
-
-        try {
-            sslServerSocket.setSoTimeout(timeout);
-            return (SSLSocket) sslServerSocket.accept();
-        } catch (SocketTimeoutException ste) {
-            print("Warning: ", ste);
-            return null;
-        }
-    }
-
-    public SSLSocketTemplate setSeparateServerThread(
-            boolean separateServerThread) {
-
-        this.separateServerThread = separateServerThread;
-        return this;
-    }
-
-    public SSLSocketTemplate setServerPort(int serverPort) {
-        this.serverPort = serverPort;
-        return this;
-    }
-
-    public int getServerPort() {
-        return serverPort;
-    }
-
-    public SSLSocketTemplate setSSLContext(SSLContext context) {
-        this.context = context;
-        return this;
-    }
-
-    public SSLContext getSSLContext() {
-        return context;
-    }
-
-    public SSLServerSocketFactory getSSLServerSocketFactory() {
-        if (context != null) {
-            return context.getServerSocketFactory();
-        }
-
-        return (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
-    }
-
-    public SSLSocketFactory getSSLSocketFactory() {
-        if (context != null) {
-            return context.getSocketFactory();
-        }
-
-        return (SSLSocketFactory) SSLSocketFactory.getDefault();
-    }
-
-    public void signalServerReady() {
-        serverReadyCondition.countDown();
-    }
-
-    public void signalServerDone() {
-        serverDoneCondition.countDown();
-    }
-
-    public boolean waitForClientSignal(long timeout, TimeUnit unit)
-            throws InterruptedException {
-
-        return clientReadyCondition.await(timeout, unit);
-    }
-
-    public boolean waitForClientSignal() throws InterruptedException {
-        return waitForClientSignal(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
-    }
-
-    public boolean waitForClientDone(long timeout, TimeUnit unit)
-            throws InterruptedException {
-
-        return clientDoneCondition.await(timeout, unit);
-    }
-
-    public boolean waitForClientDone() throws InterruptedException {
-        return waitForClientDone(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
-    }
-
-    public void signalClientReady() {
-        clientReadyCondition.countDown();
-    }
-
-    public void signalClientDone() {
-        clientDoneCondition.countDown();
-    }
-
-    public boolean waitForServerSignal(long timeout, TimeUnit unit)
-            throws InterruptedException {
-
-        return serverReadyCondition.await(timeout, unit);
-    }
-
-    public boolean waitForServerSignal() throws InterruptedException {
-        return waitForServerSignal(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
-    }
-
-    public boolean waitForServerDone(long timeout, TimeUnit unit)
-            throws InterruptedException {
-
-        return serverDoneCondition.await(timeout, unit);
-    }
-
-    public boolean waitForServerDone() throws InterruptedException {
-        return waitForServerDone(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
-    }
-
-    public SSLSocketTemplate setServerPeer(Peer serverPeer) {
-        this.serverPeer = serverPeer;
-        return this;
-    }
-
-    public Peer getServerPeer() {
-        return serverPeer;
-    }
-
-    public SSLSocketTemplate setServerApplication(
-            Application serverApplication) {
-
-        this.serverApplication = serverApplication;
-        return this;
-    }
-
-    public Application getServerApplication() {
-        return serverApplication;
-    }
-
-    public SSLSocketTemplate setClientPeer(Peer clientPeer) {
-        this.clientPeer = clientPeer;
-        return this;
-    }
-
-    public Peer getClientPeer() {
-        return clientPeer;
-    }
-
-    public SSLSocketTemplate setClientApplication(
-            Application clientApplication) {
-
-        this.clientApplication = clientApplication;
-        return this;
-    }
-
-    public Application getClientApplication() {
-        return clientApplication;
-    }
-
-    public void runTest() throws Exception {
-        if (separateServerThread) {
-            startServer(true, this);
-            startClient(false, this);
-            serverThread.join();
-        } else {
-            startClient(true, this);
-            startServer(false, this);
-            clientThread.join();
-        }
-
-        if (clientException != null || serverException != null) {
-            throw new RuntimeException("Test failed");
-        }
-    }
-
-    public SSLSocketTemplate() {
-        serverPeer = new Peer() {
-
-            @Override
-            public void run(SSLSocketTemplate test) throws Exception {
-                doServerSide(test);
-            }
-        };
-
-        clientPeer = new Peer() {
-
-            @Override
-            public void run(SSLSocketTemplate test) throws Exception {
-                doClientSide(test);
-            }
-        };
-
-        serverApplication = new Application() {
-
-            @Override
-            public void run(SSLSocket socket, SSLSocketTemplate test)
-                    throws Exception {
-
-                runServerApplication(socket);
-            }
-
-        };
-
-        clientApplication = new Application() {
-
-            @Override
-            public void run(SSLSocket socket, SSLSocketTemplate test)
-                    throws Exception {
-
-                runClientApplication(socket);
-            }
-        };
-    }
-
-    public static void main(String args[]) throws Exception {
-        // reset the security property to make sure that the algorithms
-        // and keys used in this test are not disabled.
-        Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
-        // MD5 is used in this test case, don't disable MD5 algorithm.
-        Security.setProperty(
-                "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
-
-        setup();
-
-        new SSLSocketTemplate().runTest();
-    }
-
-    /*
-     * Private part.
-     */
+    private volatile int serverPort = 0;
 
     /*
      * Define the server side of the test.
      */
-    private static void doServerSide(SSLSocketTemplate test) throws Exception {
-        SSLServerSocket sslServerSocket;
-
+    private void doServerSide() throws Exception {
         // kick start the server side service
-        SSLServerSocketFactory sslssf = test.getSSLServerSocketFactory();
-        sslServerSocket = (SSLServerSocket)sslssf.createServerSocket(FREE_PORT);
-
-        test.setServerPort(sslServerSocket.getLocalPort());
-        print("Server is listening on port " + test.getServerPort());
+        SSLContext context = createServerSSLContext();
+        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+        SSLServerSocket sslServerSocket =
+                (SSLServerSocket)sslssf.createServerSocket(serverPort);
+        serverPort = sslServerSocket.getLocalPort();
 
         // Signal the client, the server is ready to accept connection.
-        test.signalServerReady();
+        serverCondition.countDown();
 
         // Try to accept a connection in 30 seconds.
-        SSLSocket sslSocket = accept(sslServerSocket);
-        if (sslSocket == null) {
+        SSLSocket sslSocket;
+        try {
+            sslServerSocket.setSoTimeout(30000);
+            sslSocket = (SSLSocket)sslServerSocket.accept();
+        } catch (SocketTimeoutException ste) {
             // Ignore the test case if no connection within 30 seconds.
-            print("No incoming client connection in 30 seconds. "
-                    + "Ignore in server side.");
+            System.out.println(
+                "No incoming client connection in 30 seconds. " +
+                "Ignore in server side.");
             return;
+        } finally {
+            sslServerSocket.close();
         }
-        print("Server accepted connection");
 
         // handle the connection
         try {
@@ -451,84 +241,79 @@
             // connections and avoid intermittent failure, it should
             // be checked that the accepted connection is really linked
             // to the expected client.
-            boolean clientIsReady = test.waitForClientSignal();
+            boolean clientIsReady =
+                    clientCondition.await(30L, TimeUnit.SECONDS);
 
             if (clientIsReady) {
                 // Run the application in server side.
-                print("Run server application");
-                test.getServerApplication().run(sslSocket, test);
+                runServerApplication(sslSocket);
             } else {    // Otherwise, ignore
                 // We don't actually care about plain socket connections
                 // for TLS communication testing generally.  Just ignore
                 // the test if the accepted connection is not linked to
                 // the expected client or the client connection timeout
                 // in 30 seconds.
-                print("The client is not the expected one or timeout. "
-                        + "Ignore in server side.");
+                System.out.println(
+                        "The client is not the expected one or timeout. " +
+                        "Ignore in server side.");
             }
         } finally {
             sslSocket.close();
-            sslServerSocket.close();
         }
-
-        test.signalServerDone();
-    }
-
-    /*
-     * Define the server side application of the test for the specified socket.
-     */
-    private static void runServerApplication(SSLSocket socket)
-            throws Exception {
-
-        // here comes the test logic
-        InputStream sslIS = socket.getInputStream();
-        OutputStream sslOS = socket.getOutputStream();
-
-        sslIS.read();
-        sslOS.write(85);
-        sslOS.flush();
     }
 
     /*
      * Define the client side of the test.
      */
-    private static void doClientSide(SSLSocketTemplate test) throws Exception {
+    private void doClientSide() throws Exception {
 
         // Wait for server to get started.
         //
         // The server side takes care of the issue if the server cannot
         // get started in 90 seconds.  The client side would just ignore
         // the test case if the serer is not ready.
-        boolean serverIsReady = test.waitForServerSignal();
+        boolean serverIsReady =
+                serverCondition.await(90L, TimeUnit.SECONDS);
         if (!serverIsReady) {
-            print("The server is not ready yet in 90 seconds. "
-                    + "Ignore in client side.");
+            System.out.println(
+                    "The server is not ready yet in 90 seconds. " +
+                    "Ignore in client side.");
             return;
         }
 
-        SSLSocketFactory sslsf = test.getSSLSocketFactory();
-        SSLSocket sslSocket = (SSLSocket)sslsf.createSocket();
-        try {
+        if (isCustomizedClientConnection()) {
+            // Signal the server, the client is ready to communicate.
+            clientCondition.countDown();
+
+            // Run the application in client side.
+            runClientApplication(serverPort);
+
+            return;
+        }
+
+        SSLContext context = createClientSSLContext();
+        SSLSocketFactory sslsf = context.getSocketFactory();
+
+        try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {
             try {
                 sslSocket.connect(
-                        new InetSocketAddress("localhost",
-                                test.getServerPort()), CLIENT_TIMEOUT);
-                print("Client connected to server");
+                        new InetSocketAddress("localhost", serverPort), 15000);
             } catch (IOException ioe) {
                 // The server side may be impacted by naughty test cases or
                 // third party routines, and cannot accept connections.
                 //
                 // Just ignore the test if the connection cannot be
                 // established.
-                print("Cannot make a connection in 15 seconds. "
-                        + "Ignore in client side.", ioe);
+                System.out.println(
+                        "Cannot make a connection in 15 seconds. " +
+                        "Ignore in client side.");
                 return;
             }
 
             // OK, here the client and server get connected.
 
             // Signal the server, the client is ready to communicate.
-            test.signalClientReady();
+            clientCondition.countDown();
 
             // There is still a chance in theory that the server thread may
             // wait client-ready timeout and then quit.  The chance should
@@ -536,46 +321,461 @@
             // real problem.
 
             // Run the application in client side.
-            print("Run client application");
-            test.getClientApplication().run(sslSocket, test);
-        } finally {
-            sslSocket.close();
+            runClientApplication(sslSocket);
         }
-
-        test.signalClientDone();
     }
 
     /*
-     * Define the client side application of the test for the specified socket.
+     * =============================================
+     * Stuffs to customize the SSLContext instances.
+     */
+
+    /*
+     * =======================================
+     * Certificates and keys used in the test.
      */
-    private static void runClientApplication(SSLSocket socket)
-            throws Exception {
+    // Trusted certificates.
+    private final static String[] trustedCertStrs = {
+        // SHA256withECDSA, curve prime256v1
+        // Validity
+        //    Not Before: Nov 25 04:19:51 2016 GMT
+        //    Not After : Nov  5 04:19:51 2037 GMT
+        // Subject Key Identifier:
+        //    CA:48:E8:00:C1:42:BD:59:9B:79:D9:B4:B4:CE:3F:68:0C:C8:C4:0C
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIICHDCCAcGgAwIBAgIJAJtKs6ZEcVjxMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
+        "AlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+        "ZTAeFw0xNjExMjUwNDE5NTFaFw0zNzExMDUwNDE5NTFaMDsxCzAJBgNVBAYTAlVT\n" +
+        "MQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" +
+        "MBMGByqGSM49AgEGCCqGSM49AwEHA0IABKMO/AFDHZia65RaqMIBX7WBdtzFj8fz\n" +
+        "ggqMADLJhoszS6qfTUDYskETw3uHfB3KAOENsoKX446qFFPuVjxS1aejga0wgaow\n" +
+        "HQYDVR0OBBYEFMpI6ADBQr1Zm3nZtLTOP2gMyMQMMGsGA1UdIwRkMGKAFMpI6ADB\n" +
+        "Qr1Zm3nZtLTOP2gMyMQMoT+kPTA7MQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2\n" +
+        "YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2WCCQCbSrOmRHFY8TAPBgNV\n" +
+        "HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqhkjOPQQDAgNJADBGAiEA5cJ/\n" +
+        "jirBbXxzpZ6kdp/Zb/yrIBnr4jiPGJTLgRTb8s4CIQChUDfP1Zqg0qJVfqFNaL4V\n" +
+        "a0EAeJHXGZnvCGGqHzoxkg==\n" +
+        "-----END CERTIFICATE-----",
+
+        // SHA256withRSA, 2048 bits
+        // Validity
+        //     Not Before: Nov 25 04:20:02 2016 GMT
+        //     Not After : Nov  5 04:20:02 2037 GMT
+        // Subject Key Identifier:
+        //     A2:DC:55:38:E4:47:7C:8B:D3:E0:CA:FA:AD:3A:C8:4A:DD:12:A0:8E
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDpzCCAo+gAwIBAgIJAO586A+hYNXaMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
+        "BAYTAlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2Vy\n" +
+        "aXZjZTAeFw0xNjExMjUwNDIwMDJaFw0zNzExMDUwNDIwMDJaMDsxCzAJBgNVBAYT\n" +
+        "AlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+        "ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMm3veDSU4zKXO0aAHos\n" +
+        "cFRXGLBTe+MUJXAtlkNyx7VKaMZNt5wrUuqzyi/r0LFUdRfNCzZf3X8s8HPHQVii\n" +
+        "29tK0y/yeTn4sJTATSmGaAysMJQpKQcfAQ79ItcEGQ721TFQZ3kOBdgp3t/yUYAP\n" +
+        "K2tFze/QbIw72LE52SBnPPPTzyimNw7Ai2MLl4eQlyMkTs7JS07zIiAO5QYbS8s+\n" +
+        "1NW0A3Y+d0B0q8wYEoHGq7QVjOKlSAksfO0tzi4l0Zu6Uf+J5kMAyZ4ZFgEJvGvw\n" +
+        "y/OKJ+soRFH/5cy1SL8B6AWD1y7WXugeeHTHRW1eOjTxqfG1rZqTVd2lfOMER8y1\n" +
+        "bXcCAwEAAaOBrTCBqjAdBgNVHQ4EFgQUotxVOORHfIvT4Mr6rTrISt0SoI4wawYD\n" +
+        "VR0jBGQwYoAUotxVOORHfIvT4Mr6rTrISt0SoI6hP6Q9MDsxCzAJBgNVBAYTAlVT\n" +
+        "MQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZjZYIJ\n" +
+        "AO586A+hYNXaMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3\n" +
+        "DQEBCwUAA4IBAQAtNZJSFeFU6Yid0WSCs2qLAVaTyHsUNSUPUFIIhFAKxdP4DFS0\n" +
+        "+aeOFwdqizAU3kReAYULsfwEBgO51lPBSpB+9coUNQwu7cc8Q5Xqw/llRB0PrINS\n" +
+        "pZl7PW6Ur2ExTBocnUT9A/nhm8iO4PFD/Ly11sf5OdZihhX69NJ2h3a3gcrLjIpO\n" +
+        "L/ewTOgSi5xs+AGGQa+huN3YVL7dh+/rCUvMZVSBX5PloxWS5MMJi0Ui6YjwCFGO\n" +
+        "J4G9m7pI+gJs/x1UG0AgplMF2UCFfiY1SAeE2nKAeOOXAXEwEjFy0ToVTmqXx7fg\n" +
+        "m9YjhuePxlBrd2DF/YW0pc8gmLnrtm4rKPLz\n" +
+        "-----END CERTIFICATE-----",
+
+        // SHA256withDSA, 2048 bits
+        // Validity
+        //     Not Before: Nov 25 04:19:56 2016 GMT
+        //     Not After : Nov  5 04:19:56 2037 GMT
+        // Subject Key Identifier:
+        //     19:46:10:43:24:6A:A5:14:BE:E2:92:01:79:F0:4C:5F:E1:AE:81:B5
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIFCzCCBLGgAwIBAgIJAOnEn6YZD/sAMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+        "Y2UwHhcNMTYxMTI1MDQxOTU2WhcNMzcxMTA1MDQxOTU2WjA7MQswCQYDVQQGEwJV\n" +
+        "UzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2Uw\n" +
+        "ggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJa17ZYdIChv5yeYuPK3zXxgUEGGsdUD\n" +
+        "AzfQUxtMryCtc3aNgWLxsN1/QYvp9v+hh4twnG20VemCEH9Qlx06Pxg74DwSOA83\n" +
+        "SecO2y7cdgmrHpep9drxKbXVZafwBhbTSwhV+IDO7EO6+LaRvZuya/YOqNIE9ENx\n" +
+        "FVk0NrNsDB6pfDEXZsCZALMN2mcl8KGn1q7vdzJQUEV7F6uLGP33znVfmQyWJH3Y\n" +
+        "W09WVCFXHvDzZHGXDO2O2QwIU1B5AsXnOGeLnKgXzErCoNKwUbVFP0W0OVeJo4pc\n" +
+        "ZfL/8TVELGG90AuuH1V3Gsq6PdzCDPw4Uv/v5m7/6kwXqBQxAJA7jhMCIQCORIGV\n" +
+        "mHy5nBLRhIP4vC7vsTxb4CTApPVmZeL5gTIwtQKCAQB2VZLY22k2+IQM6deRGK3L\n" +
+        "l7tPChGrKnGmTbtUThIza70Sp9DmTBiLzMEY+IgG8kYuT5STVxWjs0cxXCKZGMQW\n" +
+        "tioMtiXPA2M3HA0/8E0mDLSmzb0RAd2xxnDyGsuqo1eVmx7PLjN3bn3EjhD/+j3d\n" +
+        "Jx3ZVScMGyq7sVWppUvpudEXi+2etf6GUHjrcX27juo7u4zQ1ezC/HYG1H+jEFqG\n" +
+        "hdQ6b7H+LBHZH9LegOyIZTMrzAY/TwIr77sXrNJWRoxmDErKB+8bRDybYhNJswlZ\n" +
+        "m0N5YYUlPmepgbl6XzwCv0y0d81h3bayqIPLXEUtRAl9GuM0hNAlA1Y+qSn9xLFY\n" +
+        "A4IBBQACggEAZgWC0uflwqQQP1GRU1tolmFZwyVtKre7SjYgCeQBrOa0Xnj/SLaD\n" +
+        "g1HZ1oH0hccaR/45YouJiCretbbsQ77KouldGSGqTHJgRL75Y2z5uvxa60+YxZ0Z\n" +
+        "v8xvZnj4seyOjgJLxSSYSPl5n/F70RaNiCLVz/kGe6OQ8KoAeQjdDTOHXCegO9KX\n" +
+        "tvhM7EaYc8CII9OIR7S7PXJW0hgLKynZcu/Unh02aM0ABh/uLmw1+tvo8e8KTp98\n" +
+        "NKYSVf6kV3/ya58n4h64UbIYL08JoKUM/5SFETcKAZTU0YKZbpWTM79oJMr8oYVk\n" +
+        "P9jKitNsXq0Xkzt5dSO0kfu/kM7zpnaFsqOBrTCBqjAdBgNVHQ4EFgQUGUYQQyRq\n" +
+        "pRS+4pIBefBMX+GugbUwawYDVR0jBGQwYoAUGUYQQyRqpRS+4pIBefBMX+GugbWh\n" +
+        "P6Q9MDsxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5K\n" +
+        "U1NFIFRlc3QgU2VyaXZjZYIJAOnEn6YZD/sAMA8GA1UdEwEB/wQFMAMBAf8wCwYD\n" +
+        "VR0PBAQDAgEGMAsGCWCGSAFlAwQDAgNHADBEAiAwBafz5RRR9nc4cCYoYuBlT/D9\n" +
+        "9eayhkjhBY/zYunypwIgNp/JnFR88/T4hh36QfSKBGXId9RBCM6uaOkOKnEGkps=\n" +
+        "-----END CERTIFICATE-----"
+        };
+
+    // End entity certificate.
+    private final static String[] endEntityCertStrs = {
+        // SHA256withECDSA, curve prime256v1
+        // Validity
+        //     Not Before: Nov 25 04:19:51 2016 GMT
+        //     Not After : Aug 12 04:19:51 2036 GMT
+        // Authority Key Identifier:
+        //     CA:48:E8:00:C1:42:BD:59:9B:79:D9:B4:B4:CE:3F:68:0C:C8:C4:0C
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIB1zCCAXygAwIBAgIJAPFq2QL/nUNZMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
+        "AlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+        "ZTAeFw0xNjExMjUwNDE5NTFaFw0zNjA4MTIwNDE5NTFaMFUxCzAJBgNVBAYTAlVT\n" +
+        "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n" +
+        "MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" +
+        "QgAE4yvRGVvy9iVATyuHPJVdX6+lh/GLm/sRJ5qLT/3PVFOoNIvlEVNiARo7xhyj\n" +
+        "2p6bnf32gNg5Ye+QCw20VUv9E6NPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSO\n" +
+        "hHlHZQp9hyBfSGTSQWeszqMXejAfBgNVHSMEGDAWgBTKSOgAwUK9WZt52bS0zj9o\n" +
+        "DMjEDDAKBggqhkjOPQQDAgNJADBGAiEAu3t6cvFglBAZfkhZlEwB04ZjUFqyfiRj\n" +
+        "4Hr275E4ZoQCIQDUEonJHlmA19J6oobfR5lYsmoqPm1r0DPm/IiNNKGKKA==\n" +
+        "-----END CERTIFICATE-----",
+
+        // SHA256withRSA, 2048 bits
+        // Validity
+        //     Not Before: Nov 25 04:20:02 2016 GMT
+        //     Not After : Aug 12 04:20:02 2036 GMT
+        // Authority Key Identifier:
+        //     A2:DC:55:38:E4:47:7C:8B:D3:E0:CA:FA:AD:3A:C8:4A:DD:12:A0:8E
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDdjCCAl6gAwIBAgIJAJDcIGOlAmBmMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
+        "BAYTAlVTMQ0wCwYDVQQKEwRKYXZhMR0wGwYDVQQLExRTdW5KU1NFIFRlc3QgU2Vy\n" +
+        "aXZjZTAeFw0xNjExMjUwNDIwMDJaFw0zNjA4MTIwNDIwMDJaMFUxCzAJBgNVBAYT\n" +
+        "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+        "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\n" +
+        "AQ8AMIIBCgKCAQEAp0dHrifTg2aY0sH03f2JjK2fW4DL6gLDKq0YirsNE07z54LF\n" +
+        "IeeDio49XwPjB7OpbUTC1hf/YKZ7XiRWyPa1rYozZ88emhZt+cpkyKz+nmW4avlA\n" +
+        "WnrV+gx4+bU9T+WuBWdAraBcq27Y1I26yfCEtC8k3+O0sdlHbhasF+BUDmX/n4+n\n" +
+        "ifJdbNm5eSDx8eFYHFTdjhAud3An2X6QD9WWSoJpPdDi4utHhFAlxW6osjJxsAPv\n" +
+        "zo8YsqmpCMjZcEks4ZsqiZKKiWUWUAjCcbMerDPDX29fyeo348uztvJsmNRzfcwl\n" +
+        "FtwxpYdxuZqwHi2QoNaQTGXjjbZFmjn7qEkjXwIDAQABo2MwYTALBgNVHQ8EBAMC\n" +
+        "A+gwHQYDVR0OBBYEFP+henfufE6Znr60lRkmayadVdxnMB8GA1UdIwQYMBaAFKLc\n" +
+        "VTjkR3yL0+DK+q06yErdEqCOMBIGA1UdEQEB/wQIMAaHBH8AAAEwDQYJKoZIhvcN\n" +
+        "AQELBQADggEBAK56pV2XoAIkrHFTCkWtYX518nuvkzN6a6BqPKALQlmlbJnq/lhV\n" +
+        "tPQx79b0j7tow28l2ze/3M0hRb5Ft/d/7mITZNMR+0owk4U51AU2NacRt7fpoxu5\n" +
+        "wX3hTa4VgX2+BAXeoWF+Yzy6Jj5gAVmSLzBnkTUH0d+EyL1pp+DFE3QdvZqf3+nP\n" +
+        "zkxz15h3iW8FwI+7/19MX2j2XB/sG8mJpqoszWw8lM4qCa2eWyCbqSHhPi+/+rGg\n" +
+        "dDG5uzZeOC845GEH2T3tHDA+F3WwcZG/W+4RR6ZaaHlqPKKMcwFL73YbsqdCiKBv\n" +
+        "p6sXrhIiP0oXImRBRLDlidj5TIOLfAtNM9A=\n" +
+        "-----END CERTIFICATE-----",
 
-        InputStream sslIS = socket.getInputStream();
-        OutputStream sslOS = socket.getOutputStream();
+        // SHA256withDSA, 2048 bits
+        // Validity
+        //    Not Before: Nov 25 04:19:56 2016 GMT
+        //    Not After : Aug 12 04:19:56 2036 GMT
+        // Authority Key Identifier:
+        //     19:46:10:43:24:6A:A5:14:BE:E2:92:01:79:F0:4C:5F:E1:AE:81:B5
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIE2jCCBICgAwIBAgIJAONcI1oba9V9MAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+        "Y2UwHhcNMTYxMTI1MDQxOTU2WhcNMzYwODEyMDQxOTU2WjBVMQswCQYDVQQGEwJV\n" +
+        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+        "GDAWBgNVBAMMD1JlZ3Jlc3Npb24gVGVzdDCCA0YwggI5BgcqhkjOOAQBMIICLAKC\n" +
+        "AQEAlrXtlh0gKG/nJ5i48rfNfGBQQYax1QMDN9BTG0yvIK1zdo2BYvGw3X9Bi+n2\n" +
+        "/6GHi3CcbbRV6YIQf1CXHTo/GDvgPBI4DzdJ5w7bLtx2Casel6n12vEptdVlp/AG\n" +
+        "FtNLCFX4gM7sQ7r4tpG9m7Jr9g6o0gT0Q3EVWTQ2s2wMHql8MRdmwJkAsw3aZyXw\n" +
+        "oafWru93MlBQRXsXq4sY/ffOdV+ZDJYkfdhbT1ZUIVce8PNkcZcM7Y7ZDAhTUHkC\n" +
+        "xec4Z4ucqBfMSsKg0rBRtUU/RbQ5V4mjilxl8v/xNUQsYb3QC64fVXcayro93MIM\n" +
+        "/DhS/+/mbv/qTBeoFDEAkDuOEwIhAI5EgZWYfLmcEtGEg/i8Lu+xPFvgJMCk9WZl\n" +
+        "4vmBMjC1AoIBAHZVktjbaTb4hAzp15EYrcuXu08KEasqcaZNu1ROEjNrvRKn0OZM\n" +
+        "GIvMwRj4iAbyRi5PlJNXFaOzRzFcIpkYxBa2Kgy2Jc8DYzccDT/wTSYMtKbNvREB\n" +
+        "3bHGcPIay6qjV5WbHs8uM3dufcSOEP/6Pd0nHdlVJwwbKruxVamlS+m50ReL7Z61\n" +
+        "/oZQeOtxfbuO6ju7jNDV7ML8dgbUf6MQWoaF1Dpvsf4sEdkf0t6A7IhlMyvMBj9P\n" +
+        "Aivvuxes0lZGjGYMSsoH7xtEPJtiE0mzCVmbQ3lhhSU+Z6mBuXpfPAK/TLR3zWHd\n" +
+        "trKog8tcRS1ECX0a4zSE0CUDVj6pKf3EsVgDggEFAAKCAQBEGmdP55PyE3M+Q3fU\n" +
+        "dCGq0sbKw/04xPVhaNYRnRKNR82n+wb8bMCI1vvFqXy1BB6svti4mTHbQZ8+bQXm\n" +
+        "gyce67uYMwIa5BIk6omNGCeW/kd4ruPgyFxeb6O/Y/7w6AWyRmQttlxRA5M5OhSC\n" +
+        "tVS4oVC1KK1EfHAUh7mu8S8GrWJoJAWA3PM97Oy/HSGCEUl6HGEu1m7FHPhOKeYG\n" +
+        "cLkSaov5cbCYO76smHchI+tdUciVqeL3YKQdS+KAzsQoeAZIu/WpbaI1V+5/rSG1\n" +
+        "I94uBITLCjlJfJZ1aredCDrRXOFH7qgSBhM8/WzwFpFCnnpbSKMgrcrKubsFmW9E\n" +
+        "jQhXo2MwYTALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFNA9PhQOjB+05fxxXPNqe0OT\n" +
+        "doCjMB8GA1UdIwQYMBaAFBlGEEMkaqUUvuKSAXnwTF/hroG1MBIGA1UdEQEB/wQI\n" +
+        "MAaHBH8AAAEwCwYJYIZIAWUDBAMCA0cAMEQCIE0LM2sZi+L8tjH9sgjLEwJmYZvO\n" +
+        "yqNfQnXrkTCb+MLMAiBZLaRTVJrOW3edQjum+SonKKuiN22bRclO6pGuNRCtng==\n" +
+        "-----END CERTIFICATE-----"
+        };
+
+    // Private key in the format of PKCS#8.
+    private final static String[] endEntityPrivateKeys = {
+        //
+        // EC private key related to cert endEntityCertStrs[0].
+        //
+        "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGAy4Pxrd2keM7AdP\n" +
+        "VNUMEO5iO681v4/tstVGfdXkCTuhRANCAATjK9EZW/L2JUBPK4c8lV1fr6WH8Yub\n" +
+        "+xEnmotP/c9UU6g0i+URU2IBGjvGHKPanpud/faA2Dlh75ALDbRVS/0T",
+
+        //
+        // RSA private key related to cert endEntityCertStrs[1].
+        //
+        "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnR0euJ9ODZpjS\n" +
+        "wfTd/YmMrZ9bgMvqAsMqrRiKuw0TTvPngsUh54OKjj1fA+MHs6ltRMLWF/9gpnte\n" +
+        "JFbI9rWtijNnzx6aFm35ymTIrP6eZbhq+UBaetX6DHj5tT1P5a4FZ0CtoFyrbtjU\n" +
+        "jbrJ8IS0LyTf47Sx2UduFqwX4FQOZf+fj6eJ8l1s2bl5IPHx4VgcVN2OEC53cCfZ\n" +
+        "fpAP1ZZKgmk90OLi60eEUCXFbqiyMnGwA+/OjxiyqakIyNlwSSzhmyqJkoqJZRZQ\n" +
+        "CMJxsx6sM8Nfb1/J6jfjy7O28myY1HN9zCUW3DGlh3G5mrAeLZCg1pBMZeONtkWa\n" +
+        "OfuoSSNfAgMBAAECggEAWnAHKPkPObN2XDvQj1RL0WrtBSOVG2dy7Ne4tQh8ATxm\n" +
+        "UXw56CKq03YjaANJ8xgHObQ7QlSnFTHs8PDkmrIHd1OIh09LVDNcMfhilLwyzKBi\n" +
+        "HDO1vzU6Cn5DyX1bMJ8UfodcSIKyl1zOjdwyaItIs8HpRcJuJtk57SME18PIrh9H\n" +
+        "EWchWSxTvPvKDY2bhb4vBMgVPfTQO3yc8gY/1J5vKPqDpyEuCGjV13zd/AoL/u5A\n" +
+        "sG10hQ2veJ9KAn1xwPwEoAkCdNLL8vPB1rCbeMZNamqHZRihfoOgDnnJIf3FtUFF\n" +
+        "8bS2FM2kGQR+05SZdhBmJl0obPrbBWil/2vxqeFrgQKBgQDZl1yQsFss2BKK2VAh\n" +
+        "9PKc8tU1v6RpHQZhJEDSct2slHQS5DF6bWl5kJiPevXSvcnjgoPamZf7Joii+Rds\n" +
+        "3xtPQmRw2vQmXBQzQS1YoRuh4hUlkdFWCjUNNg1kvipue6FO4PVg3ViP7llN8PXK\n" +
+        "rSpVxn0a36UiN9jN2zMOUs6tJwKBgQDEzlqa7DghMli7TUdL44uvD2/ceiHqHMMw\n" +
+        "5eLsEHeRVn/EVU99beKw/dAOGwRssTpCd9h7fwzQ2503/Qb/Goe0nKE7+xvt3/sE\n" +
+        "n2Y8Qfv1W1+hGb2qU2jhQaR5bZrLZp0+BgRuQ4ttpYvzopYe4FLZWhDBA0zsGyu0\n" +
+        "nCi7lUSrCQKBgGeGYW8hyS9r2l6fiEWvsiLEUnbRKFsuiRN82S6HojpzI0q9sWDL\n" +
+        "X6yMBFn3qa/LxpttRGikPTAsJERN+Tw+ZlLuhrU/J3x8wMumDfomJOx/kYofd5bV\n" +
+        "ImqXtgWhiLSqM5RA6d5dUb6hK3Iu2/LDMuo+ltVLZNkD8y32RbNh6J1vAoGAbLqQ\n" +
+        "pgyhSf3Vtc0Q+aVB87p0k3tKJ1wynl4zSzYhyMLgHakAHIzL8/qVqmVUwXP8euJZ\n" +
+        "UIk1nGHobxk0d1XB6Y+rKEcn+/iFZt1ljx7pQ3ly0L824NXqGKC6bHeYUI1li/Gp\n" +
+        "Gv3oFvCh7D1D8NUAEKLIpMndAohUUhkAC/qAkHkCgYEAzSIarDNquayV+umC1SXm\n" +
+        "Zo6XLuzWjudLxPd2lyCfwR2aRKlrb+5OFYErX+RSLyCJmaqVZMyXP09PBIvNXu2Z\n" +
+        "+gbx5WUC+kA+6zdKEPXowei6i6EHMXYT2AL7395ZbPajZjsCduE3WuUztuHrhtMm\n" +
+        "JI+k1o4rCnSLlX4gWdN1oTs=",
+
+        //
+        // DSA private key related to cert endEntityCertStrs[2].
+        //
+        "MIICZAIBADCCAjkGByqGSM44BAEwggIsAoIBAQCWte2WHSAob+cnmLjyt818YFBB\n" +
+        "hrHVAwM30FMbTK8grXN2jYFi8bDdf0GL6fb/oYeLcJxttFXpghB/UJcdOj8YO+A8\n" +
+        "EjgPN0nnDtsu3HYJqx6XqfXa8Sm11WWn8AYW00sIVfiAzuxDuvi2kb2bsmv2DqjS\n" +
+        "BPRDcRVZNDazbAweqXwxF2bAmQCzDdpnJfChp9au73cyUFBFexerixj99851X5kM\n" +
+        "liR92FtPVlQhVx7w82RxlwztjtkMCFNQeQLF5zhni5yoF8xKwqDSsFG1RT9FtDlX\n" +
+        "iaOKXGXy//E1RCxhvdALrh9VdxrKuj3cwgz8OFL/7+Zu/+pMF6gUMQCQO44TAiEA\n" +
+        "jkSBlZh8uZwS0YSD+Lwu77E8W+AkwKT1ZmXi+YEyMLUCggEAdlWS2NtpNviEDOnX\n" +
+        "kRity5e7TwoRqypxpk27VE4SM2u9EqfQ5kwYi8zBGPiIBvJGLk+Uk1cVo7NHMVwi\n" +
+        "mRjEFrYqDLYlzwNjNxwNP/BNJgy0ps29EQHdscZw8hrLqqNXlZsezy4zd259xI4Q\n" +
+        "//o93Scd2VUnDBsqu7FVqaVL6bnRF4vtnrX+hlB463F9u47qO7uM0NXswvx2BtR/\n" +
+        "oxBahoXUOm+x/iwR2R/S3oDsiGUzK8wGP08CK++7F6zSVkaMZgxKygfvG0Q8m2IT\n" +
+        "SbMJWZtDeWGFJT5nqYG5el88Ar9MtHfNYd22sqiDy1xFLUQJfRrjNITQJQNWPqkp\n" +
+        "/cSxWAQiAiAKHYbYwEy0XS9J0MeKQmqPswn0nCJKvH+esfMKkZvV3w=="
+        };
 
-        sslOS.write(280);
-        sslOS.flush();
-        sslIS.read();
+    // Private key names of endEntityPrivateKeys.
+    private final static String[] endEntityPrivateKeyNames = {
+        "EC",
+        "RSA",
+        "DSA",
+        };
+
+    /*
+     * Create an instance of SSLContext with the specified trust/key materials.
+     */
+    private SSLContext createSSLContext(
+            String[] trustedMaterials,
+            String[] keyMaterialCerts,
+            String[] keyMaterialKeys,
+            String[] keyMaterialKeyAlgs,
+            ContextParameters params) throws Exception {
+
+        KeyStore ts = null;     // trust store
+        KeyStore ks = null;     // key store
+        char passphrase[] = "passphrase".toCharArray();
+
+        // Generate certificate from cert string.
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+        // Import the trused certs.
+        ByteArrayInputStream is;
+        if (trustedMaterials != null && trustedMaterials.length != 0) {
+            ts = KeyStore.getInstance("JKS");
+            ts.load(null, null);
+
+            Certificate[] trustedCert =
+                    new Certificate[trustedMaterials.length];
+            for (int i = 0; i < trustedMaterials.length; i++) {
+                String trustedCertStr = trustedMaterials[i];
+
+                is = new ByteArrayInputStream(trustedCertStr.getBytes());
+                try {
+                    trustedCert[i] = cf.generateCertificate(is);
+                } finally {
+                    is.close();
+                }
+
+                ts.setCertificateEntry("trusted-cert-" + i, trustedCert[i]);
+            }
+        }
+
+        // Import the key materials.
+        //
+        // Note that certification pathes bigger than one are not supported yet.
+        boolean hasKeyMaterials =
+            (keyMaterialCerts != null) && (keyMaterialCerts.length != 0) &&
+            (keyMaterialKeys != null) && (keyMaterialKeys.length != 0) &&
+            (keyMaterialKeyAlgs != null) && (keyMaterialKeyAlgs.length != 0) &&
+            (keyMaterialCerts.length == keyMaterialKeys.length) &&
+            (keyMaterialCerts.length == keyMaterialKeyAlgs.length);
+        if (hasKeyMaterials) {
+            ks = KeyStore.getInstance("JKS");
+            ks.load(null, null);
+
+            for (int i = 0; i < keyMaterialCerts.length; i++) {
+                String keyCertStr = keyMaterialCerts[i];
+
+                // generate the private key.
+                PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+                    Base64.getMimeDecoder().decode(keyMaterialKeys[i]));
+                KeyFactory kf =
+                    KeyFactory.getInstance(keyMaterialKeyAlgs[i]);
+                PrivateKey priKey = kf.generatePrivate(priKeySpec);
+
+                // generate certificate chain
+                is = new ByteArrayInputStream(keyCertStr.getBytes());
+                Certificate keyCert = null;
+                try {
+                    keyCert = cf.generateCertificate(is);
+                } finally {
+                    is.close();
+                }
+
+                Certificate[] chain = new Certificate[] { keyCert };
+
+                // import the key entry.
+                ks.setKeyEntry("cert-" + keyMaterialKeyAlgs[i],
+                        priKey, passphrase, chain);
+            }
+        }
+
+        // Create an SSLContext object.
+        TrustManagerFactory tmf =
+                TrustManagerFactory.getInstance(params.tmAlgorithm);
+        tmf.init(ts);
+
+        SSLContext context = SSLContext.getInstance(params.contextProtocol);
+        if (hasKeyMaterials && ks != null) {
+            KeyManagerFactory kmf =
+                    KeyManagerFactory.getInstance(params.kmAlgorithm);
+            kmf.init(ks, passphrase);
+
+            context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+        } else {
+            context.init(null, tmf.getTrustManagers(), null);
+        }
+
+        return context;
     }
 
-    private void startServer(boolean newThread, SSLSocketTemplate test)
-            throws Exception {
+    /*
+     * =================================================
+     * Stuffs to boot up the client-server mode testing.
+     */
+    private Thread clientThread = null;
+    private Thread serverThread = null;
+    private volatile Exception serverException = null;
+    private volatile Exception clientException = null;
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    private static final boolean separateServerThread = false;
+
+    /*
+     * Boot up the testing, used to drive remainder of the test.
+     */
+    private void bootup() throws Exception {
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            startException = e;
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            if (serverThread != null) {
+                serverThread.join();
+            }
+        } else {
+            if (clientThread != null) {
+                clientThread.join();
+            }
+        }
 
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
+         */
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
+    }
+
+    private void startServer(boolean newThread) throws Exception {
         if (newThread) {
             serverThread = new Thread() {
-
                 @Override
                 public void run() {
                     try {
-                        serverPeer.run(test);
+                        doServerSide();
                     } catch (Exception e) {
                         /*
                          * Our server thread just died.
                          *
                          * Release the client, if not active already...
                          */
-                        print("Server died ...", e);
+                        logException("Server died", e);
                         serverException = e;
                     }
                 }
@@ -583,29 +783,26 @@
             serverThread.start();
         } else {
             try {
-                serverPeer.run(test);
+                doServerSide();
             } catch (Exception e) {
-                print("Server failed ...", e);
+                logException("Server failed", e);
                 serverException = e;
             }
         }
     }
 
-    private void startClient(boolean newThread, SSLSocketTemplate test)
-            throws Exception {
-
+    private void startClient(boolean newThread) throws Exception {
         if (newThread) {
             clientThread = new Thread() {
-
                 @Override
                 public void run() {
                     try {
-                        clientPeer.run(test);
+                        doClientSide();
                     } catch (Exception e) {
                         /*
                          * Our client thread just died.
                          */
-                        print("Client died ...", e);
+                        logException("Client died", e);
                         clientException = e;
                     }
                 }
@@ -613,11 +810,16 @@
             clientThread.start();
         } else {
             try {
-                clientPeer.run(test);
+                doClientSide();
             } catch (Exception e) {
-                print("Client failed ...", e);
+                logException("Client failed", e);
                 clientException = e;
             }
         }
     }
+
+    private synchronized void logException(String prefix, Throwable cause) {
+        System.out.println(prefix + ": " + cause);
+        cause.printStackTrace(System.out);
+    }
 }
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4323990 4413069 8160838
@@ -29,19 +34,25 @@
  * @modules java.base/sun.net.www
  * @library /javax/net/ssl/templates
  * @run main/othervm ProxyAuthTest fail
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic ProxyAuthTest fail
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic, ProxyAuthTest fail
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=BAsIc ProxyAuthTest fail
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,Digest ProxyAuthTest fail
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Unknown,bAsIc ProxyAuthTest fail
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= ProxyAuthTest succeed
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Digest,NTLM,Negotiate ProxyAuthTest succeed
- * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=UNKNOWN,notKnown ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic
+ *      ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,
+ *      ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=BAsIc
+ *      ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,Digest
+ *      ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Unknown,bAsIc
+ *      ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=
+ *      ProxyAuthTest succeed
+ * @run main/othervm
+ *      -Djdk.http.auth.tunneling.disabledSchemes=Digest,NTLM,Negotiate
+ *      ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=UNKNOWN,notKnown
+ *      ProxyAuthTest succeed
  */
 
-// No way to reserve and restore java.lang.Authenticator, as well as read-once
-// system properties, so this tests needs to run in othervm mode.
-
 import java.io.BufferedReader;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -54,6 +65,8 @@
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLContext;
 import static java.nio.charset.StandardCharsets.US_ASCII;
 
 /*
@@ -64,13 +77,128 @@
  */
 
 public class ProxyAuthTest extends SSLSocketTemplate {
+    private static boolean expectSuccess;
+
     /*
-     * Where do we find the keystores?
+     * Run the test case.
      */
-    static String pathToStores = "../../../../../../javax/net/ssl/etc";
-    static String keyStoreFile = "keystore";
-    static String trustStoreFile = "truststore";
-    static String passwd = "passphrase";
+    public static void main(String[] args) throws Exception {
+        // Get the customized arguments.
+        parseArguments(args);
+
+        (new ProxyAuthTest()).run();
+    }
+
+    @Override
+    protected boolean isCustomizedClientConnection() {
+        return true;
+    }
+
+    @Override
+    protected void runServerApplication(SSLSocket socket) throws Exception {
+        String response = "Proxy authentication for tunneling succeeded ..";
+        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+        try {
+            BufferedReader in = new BufferedReader(
+                    new InputStreamReader(socket.getInputStream()));
+
+            // read the request
+            readRequest(in);
+
+            // retrieve bytecodes
+            byte[] bytecodes = response.getBytes(US_ASCII);
+
+            // send bytecodes in response (assumes HTTP/1.0 or later)
+            out.writeBytes("HTTP/1.0 200 OK\r\n");
+            out.writeBytes("Content-Length: " + bytecodes.length + "\r\n");
+            out.writeBytes("Content-Type: text/html\r\n\r\n");
+            out.write(bytecodes);
+            out.flush();
+        } catch (IOException e) {
+            // write out error response
+            out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
+            out.writeBytes("Content-Type: text/html\r\n\r\n");
+            out.flush();
+        }
+    }
+
+    @Override
+    protected void runClientApplication(int serverPort) throws Exception {
+        /*
+         * Set the default SSLSocketFactory.
+         */
+        SSLContext context = createClientSSLContext();
+        HttpsURLConnection.setDefaultSSLSocketFactory(
+                context.getSocketFactory());
+
+        /*
+         * setup up a proxy with authentication information
+         */
+        ProxyTunnelServer ps = setupProxy();
+
+        /*
+         * we want to avoid URLspoofCheck failures in cases where the cert
+         * DN name does not match the hostname in the URL.
+         */
+        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+
+        InetSocketAddress paddr =
+                new InetSocketAddress("localhost", ps.getPort());
+        Proxy proxy = new Proxy(Proxy.Type.HTTP, paddr);
+
+        URL url = new URL(
+                "https://" + "localhost:" + serverPort + "/index.html");
+        BufferedReader in = null;
+        HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(proxy);
+        try {
+            in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
+            String inputLine;
+            System.out.print("Client recieved from the server: ");
+            while ((inputLine = in.readLine()) != null) {
+                System.out.println(inputLine);
+            }
+            if (!expectSuccess) {
+                throw new RuntimeException(
+                    "Expected exception/failure to connect, but succeeded.");
+            }
+        } catch (IOException e) {
+            if (expectSuccess) {
+                System.out.println("Client side failed: " + e.getMessage());
+                throw e;
+            }
+
+            // Assert that the error stream is not accessible from the failed
+            // tunnel setup.
+            if (uc.getErrorStream() != null) {
+                throw new RuntimeException("Unexpected error stream.");
+            }
+
+            if (!e.getMessage().contains("Unable to tunnel through proxy") ||
+                !e.getMessage().contains("407")) {
+
+                throw new RuntimeException(
+                        "Expected exception about cannot tunnel, " +
+                        "407, etc, but got", e);
+            } else {
+                // Informative
+                System.out.println(
+                        "Caught expected exception: " + e.getMessage());
+            }
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+        }
+    }
+
+
+    private static void parseArguments(String[] args) {
+        if (args[0].equals("succeed")) {
+            expectSuccess = true;
+        } else {
+            expectSuccess = false;
+        }
+    }
 
     /**
      * read the response, don't care for the syntax of the request-line
@@ -88,143 +216,7 @@
                 (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
     }
 
-    /*
-     * Main method to create the server and the client
-     */
-    public static void main(String args[]) throws Exception {
-        boolean expectSuccess;
-        expectSuccess = args[0].equals("succeed");
-
-        String keyFilename =
-            TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
-        String trustFilename =
-            TEST_SRC + "/" + pathToStores + "/" + trustStoreFile;
-
-        setup(keyFilename, trustFilename, passwd);
-
-        new SSLSocketTemplate()
-            .setServerApplication((socket, test) -> {
-                DataOutputStream out = new DataOutputStream(
-                        socket.getOutputStream());
-
-                try {
-                    BufferedReader in = new BufferedReader(
-                            new InputStreamReader(socket.getInputStream()));
-
-                    // read the request
-                    readRequest(in);
-
-                    // retrieve bytecodes
-                    byte[] bytecodes =
-                            "Proxy authentication for tunneling succeeded .."
-                                    .getBytes(US_ASCII);
-
-                    // send bytecodes in response (assumes HTTP/1.0 or later)
-                    out.writeBytes("HTTP/1.0 200 OK\r\n");
-                    out.writeBytes("Content-Length: " + bytecodes.length +
-                                   "\r\n");
-                    out.writeBytes("Content-Type: text/html\r\n\r\n");
-                    out.write(bytecodes);
-                    out.flush();
-                } catch (IOException e) {
-                    // write out error response
-                    out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
-                    out.writeBytes("Content-Type: text/html\r\n\r\n");
-                    out.flush();
-                }
-            })
-            .setClientPeer(test -> {
-                try {
-                    doClientSide(test);
-                    if (!expectSuccess) {
-                        throw new RuntimeException("Expected exception/failure "
-                                + "to connect, but succeeded.");
-                    }
-                } catch (IOException e) {
-                    if (expectSuccess) {
-                        System.out.println("Client side failed: "
-                                + e.getMessage());
-                        throw e;
-                    }
-
-                    if (! (e.getMessage().contains(
-                                "Unable to tunnel through proxy") &&
-                           e.getMessage().contains("407")) ) {
-
-                        throw new RuntimeException(
-                                "Expected exception about cannot tunnel, "
-                                        + "407, etc, but got", e);
-                    } else {
-                        // Informative
-                        System.out.println("Caught expected exception: "
-                                + e.getMessage());
-                    }
-                }
-            })
-            .runTest();
-    }
-
-    static void doClientSide(SSLSocketTemplate test) throws IOException {
-
-        // Wait for server to get started.
-        //
-        // The server side takes care of the issue if the server cannot
-        // get started in 90 seconds.  The client side would just ignore
-        // the test case if the serer is not ready.
-        try {
-            if (!test.waitForServerSignal()) {
-                System.out.print("The server is not ready yet in 90 seconds. "
-                        + "Ignore in client side.");
-                return;
-            }
-        } catch (InterruptedException e) {
-            System.out.print("InterruptedException occured. "
-                    + "Ignore in client side.");
-            return;
-        }
-
-        /*
-         * setup up a proxy with authentication information
-         */
-        ProxyTunnelServer ps = setupProxy();
-
-        /*
-         * we want to avoid URLspoofCheck failures in cases where the cert
-         * DN name does not match the hostname in the URL.
-         */
-        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-
-        InetSocketAddress paddr = new InetSocketAddress(
-                "localhost", ps.getPort());
-        Proxy proxy = new Proxy(Proxy.Type.HTTP, paddr);
-
-        URL url = new URL("https://" + "localhost:" + test.getServerPort()
-                + "/index.html");
-
-        // Signal the server, the client is ready to communicate.
-        test.signalClientReady();
-
-        HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(proxy);
-        try (BufferedReader in = new BufferedReader(
-                new InputStreamReader(uc.getInputStream()))) {
-
-            String inputLine;
-            System.out.print("Client recieved from the server: ");
-            while ((inputLine = in.readLine()) != null) {
-                System.out.println(inputLine);
-            }
-        } catch (IOException e) {
-            // Assert that the error stream is not accessible from the failed
-            // tunnel setup.
-            if (uc.getErrorStream() != null) {
-                throw new RuntimeException("Unexpected error stream.");
-            }
-
-            throw e;
-        }
-    }
-
-    static class NameVerifier implements HostnameVerifier {
+    private static class NameVerifier implements HostnameVerifier {
 
         @Override
         public boolean verify(String hostname, SSLSession session) {
@@ -232,8 +224,9 @@
         }
     }
 
-    static ProxyTunnelServer setupProxy() throws IOException {
+    private static ProxyTunnelServer setupProxy() throws IOException {
         ProxyTunnelServer pserver = new ProxyTunnelServer();
+
         /*
          * register a system wide authenticator and setup the proxy for
          * authentication
@@ -248,7 +241,7 @@
         return pserver;
     }
 
-    public static class TestAuthenticator extends Authenticator {
+    private static class TestAuthenticator extends Authenticator {
 
         @Override
         public PasswordAuthentication getPasswordAuthentication() {
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -21,86 +21,109 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4328195
  * @summary Need to include the alternate subject DN for certs,
  *          https should check for this
  * @library /javax/net/ssl/templates
- * @run main/othervm ServerIdentityTest dnsstore
- * @run main/othervm ServerIdentityTest ipstore
- *
- *     SunJSSE does not support dynamic system properties, no way to re-use
- *     system properties in samevm/agentvm mode.
+ * @run main/othervm ServerIdentityTest dnsstore localhost
+ * @run main/othervm ServerIdentityTest ipstore 127.0.0.1
  *
  * @author Yingxian Wang
  */
 
+import java.io.InputStream;
 import java.io.BufferedWriter;
 import java.io.OutputStreamWriter;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.security.KeyStore;
 import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+
+public final class ServerIdentityTest extends SSLSocketTemplate {
 
-public class ServerIdentityTest extends SSLSocketTemplate {
+    private static String keystore;
+    private static String hostname;
+    private static SSLContext context;
 
-    private static final String PASSWORD = "changeit";
-
+    /*
+     * Run the test case.
+     */
     public static void main(String[] args) throws Exception {
-        final String keystore = args[0];
-        String keystoreFilename = TEST_SRC + "/" + keystore;
+        // Get the customized arguments.
+        initialize(args);
+
+        (new ServerIdentityTest()).run();
+    }
+
+    @Override
+    protected boolean isCustomizedClientConnection() {
+        return true;
+    }
 
-        setup(keystoreFilename, keystoreFilename, PASSWORD);
+    @Override
+    protected void runServerApplication(SSLSocket socket) throws Exception {
+        BufferedWriter bw = new BufferedWriter(
+                new OutputStreamWriter(socket.getOutputStream()));
+        bw.write("HTTP/1.1 200 OK\r\n\r\n\r\n");
+        bw.flush();
+        socket.getSession().invalidate();
+    }
+
+    @Override
+    protected void runClientApplication(int serverPort) throws Exception {
+        URL url = new URL(
+                "https://" + hostname + ":" + serverPort + "/index.html");
 
-        SSLContext context = SSLContext.getInstance("SSL");
+        HttpURLConnection urlc = null;
+        InputStream is = null;
+        try {
+            urlc = (HttpURLConnection)url.openConnection();
+            is = urlc.getInputStream();
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+            if (urlc != null) {
+                urlc.disconnect();
+            }
+        }
+    }
+
+    @Override
+    protected SSLContext createServerSSLContext() throws Exception {
+        return context;
+    }
 
-        KeyManager[] kms = new KeyManager[1];
-        KeyStore ks = loadJksKeyStore(keystoreFilename, PASSWORD);
-        KeyManager km = new MyKeyManager(ks, PASSWORD.toCharArray());
-        kms[0] = km;
-        context.init(kms, null, null);
+    @Override
+    protected SSLContext createClientSSLContext() throws Exception {
+        return context;
+    }
+
+    private static void initialize(String[] args) throws Exception {
+        keystore = args[0];
+        hostname = args[1];
+
+        String password = "changeit";
+        String keyFilename =
+                System.getProperty("test.src", ".") + "/" + keystore;
+        String trustFilename =
+                System.getProperty("test.src", ".") + "/" + keystore;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", password);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", password);
+
+        context = SSLContext.getDefault();
         HttpsURLConnection.setDefaultSSLSocketFactory(
                 context.getSocketFactory());
-
-        /*
-         * Start the test.
-         */
-        System.out.println("Testing " + keystore);
-
-        new SSLSocketTemplate()
-            .setSSLContext(context)
-            .setServerApplication((socket, test) -> {
-                BufferedWriter bw = new BufferedWriter(
-                        new OutputStreamWriter(socket.getOutputStream()));
-                bw.write("HTTP/1.1 200 OK\r\n\r\n\r\n");
-                bw.flush();
-                Thread.sleep(2000);
-                socket.getSession().invalidate();
-                print("Server application is done");
-            })
-            .setClientPeer((test) -> {
-                boolean serverIsReady = test.waitForServerSignal();
-                if (!serverIsReady) {
-                    print(
-                            "The server is not ready, ignore on client side.");
-                    return;
-                }
-
-                // Signal the server, the client is ready to communicate.
-                test.signalClientReady();
-
-                String host = keystore.equals("ipstore")
-                        ? "127.0.0.1" : "localhost";
-                URL url = new URL("https://" + host + ":" + test.getServerPort()
-                        + "/index.html");
-
-                ((HttpURLConnection) url.openConnection())
-                        .getInputStream().close();
-
-                print("Client is done");
-            }).runTest();
     }
 }
--- a/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java	Tue Dec 13 02:04:23 2016 +0100
@@ -31,115 +31,57 @@
  * @bug 4392475
  * @library /javax/net/ssl/templates
  * @summary Calling setWantClientAuth(true) disables anonymous suites
- * @run main/othervm/timeout=180 AnonCipherWithWantClientAuth
+ * @run main/othervm AnonCipherWithWantClientAuth
  */
 
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.security.Security;
-
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSocket;
 
 public class AnonCipherWithWantClientAuth extends SSLSocketTemplate {
-
     /*
-     * Where do we find the keystores?
+     * Run the test case.
      */
-    static String pathToStores = "../../../../javax/net/ssl/etc";
-    static String keyStoreFile = "keystore";
-    static String trustStoreFile = "truststore";
-    static String passwd = "passphrase";
-
     public static void main(String[] args) throws Exception {
+        // reset the security property to make sure that the algorithms
+        // and keys used in this test are not disabled.
         Security.setProperty("jdk.tls.disabledAlgorithms", "");
         Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
-        String keyFilename =
-            System.getProperty("test.src", "./") + "/" + pathToStores +
-                "/" + keyStoreFile;
-        String trustFilename =
-            System.getProperty("test.src", "./") + "/" + pathToStores +
-                "/" + trustStoreFile;
-        setup(keyFilename, trustFilename, passwd);
-
-        new SSLSocketTemplate()
-            .setServerPeer(test -> {
-                SSLServerSocketFactory sslssf =
-                        (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
-                SSLServerSocket sslServerSocket =
-                        (SSLServerSocket) sslssf.createServerSocket(FREE_PORT);
-                test.setServerPort(sslServerSocket.getLocalPort());
-                print("Server is listening on port "
-                        + test.getServerPort());
+        (new AnonCipherWithWantClientAuth()).run();
+    }
 
-                String ciphers[] = {
-                        "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-                        "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
-                        "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" };
-                sslServerSocket.setEnabledCipherSuites(ciphers);
-                sslServerSocket.setWantClientAuth(true);
-
-                // Signal the client, the server is ready to accept connection.
-                test.signalServerReady();
+    @Override
+    protected void runServerApplication(SSLSocket socket) throws Exception {
+        String ciphers[] = {
+                "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+                "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+                "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" };
+        socket.setEnabledCipherSuites(ciphers);
+        socket.setWantClientAuth(true);
 
-                // Try to accept a connection in 30 seconds.
-                SSLSocket sslSocket = accept(sslServerSocket);
-                if (sslSocket == null) {
-                    // Ignore the test case if no connection within 30 seconds.
-                    print("No incoming client connection in 30 seconds."
-                            + " Ignore in server side.");
-                    return;
-                }
-                print("Server accepted connection");
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
 
-                // handle the connection
-                try {
-                    // Is it the expected client connection?
-                    //
-                    // Naughty test cases or third party routines may try to
-                    // connection to this server port unintentionally.  In
-                    // order to mitigate the impact of unexpected client
-                    // connections and avoid intermittent failure, it should
-                    // be checked that the accepted connection is really linked
-                    // to the expected client.
-                    boolean clientIsReady = test.waitForClientSignal();
-
-                    if (clientIsReady) {
-                        // Run the application in server side.
-                        print("Run server application");
-
-                        InputStream sslIS = sslSocket.getInputStream();
-                        OutputStream sslOS = sslSocket.getOutputStream();
+        sslIS.read();
+        sslOS.write(85);
+        sslOS.flush();
+    }
 
-                        sslIS.read();
-                        sslOS.write(85);
-                        sslOS.flush();
-                    } else {
-                        System.out.println(
-                                "The client is not the expected one or timeout. "
-                                        + "Ignore in server side.");
-                    }
-                } finally {
-                    sslSocket.close();
-                    sslServerSocket.close();
-                }
-            })
-            .setClientApplication((socket, test) -> {
-                String ciphers[] = {
-                        "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-                        "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5" };
-                socket.setEnabledCipherSuites(ciphers);
-                socket.setUseClientMode(true);
+    @Override
+    protected void runClientApplication(SSLSocket socket) throws Exception {
+        String ciphers[] = {
+                "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+                "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5" };
+        socket.setEnabledCipherSuites(ciphers);
+        socket.setUseClientMode(true);
 
-                InputStream sslIS = socket.getInputStream();
-                OutputStream sslOS = socket.getOutputStream();
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
 
-                sslOS.write(280);
-                sslOS.flush();
-                sslIS.read();
-            })
-            .runTest();
+        sslOS.write(280);
+        sslOS.flush();
+        sslIS.read();
     }
 }
--- a/jdk/test/sun/text/resources/LocaleData	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/text/resources/LocaleData	Tue Dec 13 02:04:23 2016 +0100
@@ -8286,6 +8286,19 @@
 # bug #8129361
 CurrencyNames//hrk=Kuna
 
+# bug #7037368
+CurrencyNames/de/sar=Saudi-Rial
+CurrencyNames/de/xpf=CFP-Franc
+CurrencyNames/it/azn=manat azero
+CurrencyNames/it/ron=leu rumeno
+CurrencyNames/it/trl=lira turca (1922-2005)
+CurrencyNames/it/try=lira turca
+CurrencyNames/sv/bgl=bulgarisk h\u00e5rd lev (1962–1999)
+CurrencyNames/sv/xaf=centralafrikansk franc
+CurrencyNames/sv/xfu=internationella j\u00e4rnv\u00e4gsunionens franc
+CurrencyNames/sv/xof=v\u00e4stafrikansk franc
+CurrencyNames/zh_CN/sdg=\u82cf\u4e39\u9551
+
 # bug #8164784
 CurrencyNames//mwk=Malawian Malawi Kwacha
 CurrencyNames//pen=Peruvian Sol
--- a/jdk/test/sun/text/resources/LocaleDataTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -37,7 +37,7 @@
  *      7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
  *      7114053 7074882 7040556 8008577 8013836 8021121 6192407 6931564 8027695
  *      8017142 8037343 8055222 8042126 8074791 8075173 8080774 8129361 8134916
- *      8145136 8145952 8164784 8037111 8081643
+ *      8145136 8145952 8164784 8037111 8081643 7037368
  * @summary Verify locale data
  * @modules java.base/sun.util.resources
  * @modules jdk.localedata
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION	Tue Dec 13 02:04:23 2016 +0100
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2016i
+tzdata2016j
--- a/jdk/test/sun/util/calendar/zi/tzdata/africa	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/util/calendar/zi/tzdata/africa	Tue Dec 13 02:04:23 2016 +0100
@@ -142,7 +142,7 @@
 # Cameroon
 # See Africa/Lagos.
 
-# Cape Verde
+# Cape Verde / Cabo Verde
 #
 # Shanks gives 1907 for the transition to CVT.
 # Perhaps the 1911-05-26 Portuguese decree
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia	Tue Dec 13 02:04:23 2016 +0100
@@ -1606,12 +1606,12 @@
 # was "blended" with the Central zone.  Therefore, Kazakhstan now has
 # two time zones, and difference between them is one hour.  The zone
 # closer to UTC is the former Western zone (probably still called the
-# same), encompassing four provinces in the west: Aqtobe, Atyrau,
-# Mangghystau, and West Kazakhstan.  The other zone encompasses
+# same), encompassing four provinces in the west: Aqtöbe, Atyraū,
+# Mangghystaū, and West Kazakhstan.  The other zone encompasses
 # everything else....  I guess that would make Kazakhstan time zones
 # de jure UTC+5 and UTC+6 respectively.
 
-# From Stepan Golosunov (2016-03-27) ([*] means see later comments below):
+# From Stepan Golosunov (2016-03-27):
 # Review of the linked documents from http://adilet.zan.kz/
 # produced the following data for post-1991 Kazakhstan:
 #
@@ -1657,7 +1657,7 @@
 #
 # This implies that on 1991-03-31 Asia/Oral remained on +04/+05 while
 # the rest of Kazakhstan switched from +06/+07 to +05/06 or from +05/06
-# to +04/+05. It's unclear how Kzyl-Orda oblast moved into the fifth
+# to +04/+05. It's unclear how Qyzylorda oblast moved into the fifth
 # time belt. (By switching from +04/+05 to +05/+06 on 1991-09-29?) ...
 #
 # 1. Act of the Cabinet of Ministers of the Republic of Kazakhstan
@@ -1670,25 +1670,25 @@
 # on the whole territory of Kazakhstan 1 hour forward on 1992-01-19 at
 # 2:00, specified DST rules.  It acknowledged that Kazakhstan was
 # located in the fourth and the fifth time belts and specified the
-# border between them to be located east of Kustanay and Aktyubinsk
-# oblasts (notably including Turgai and Kzyl-Orda oblasts into the fifth
+# border between them to be located east of Qostanay and Aktyubinsk
+# oblasts (notably including Turgai and Qyzylorda oblasts into the fifth
 # time belt).
 #
 # This means switch on 1992-01-19 at 2:00 from +04/+05 to +05/+06 for
-# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyrau and Kustanay oblasts; from
-# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk) [*]....
+# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyraū and Qostanay oblasts; from
+# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk)....
 #
 # 2. Act of the Cabinet of Ministers of the Republic of Kazakhstan
 # from 1992-03-27 No. 284
 # http://adilet.zan.kz/rus/docs/P920000284_
-# cancels extra hour ("decree time") for Uralsk and Kzyl-Orda oblasts
+# cancels extra hour ("decree time") for Uralsk and Qyzylorda oblasts
 # since the last Sunday of March 1992, while keeping them in the fourth
 # and the fifth time belts respectively.
 #
 # 3. Order of the Prime Minister of the Republic of Kazakhstan
 # from 1994-09-23 No. 384
 # http://adilet.zan.kz/rus/docs/R940000384_
-# cancels the extra hour ("decree time") on the territory of Mangystau
+# cancels the extra hour ("decree time") on the territory of Mangghystaū
 # oblast since the last Sunday of September 1994 (saying that time on
 # the territory would correspond to the third time belt as a
 # result)....
@@ -1702,14 +1702,11 @@
 # 5. Act of the Government of the Republic of Kazakhstan
 # from 1999-03-26 No. 305
 # http://adilet.zan.kz/rus/docs/P990000305_
-# cancels the extra hour ("decree time") for Atyrau oblast since the
+# cancels the extra hour ("decree time") for Atyraū oblast since the
 # last Sunday of March 1999 while retaining the oblast in the fourth
 # time belt.
 #
-# This means change from +05/+06 to +04/+05.
-#
-# There is no zone for Atyrau currently (listed under Asia/Aqtau in
-# zone1970.tab).[*]
+# This means change from +05/+06 to +04/+05....
 #
 # 6. Act of the Government of the Republic of Kazakhstan
 # from 2000-11-23 No. 1749
@@ -1719,10 +1716,10 @@
 # The only changes I noticed are in definition of the border between the
 # fourth and the fifth time belts.  They account for changes in spelling
 # and administrative division (splitting of Turgai oblast in 1997
-# probably changed time in territories incorporated into Kostanay oblast
-# (including Arkalyk) from +06/+07 to +05/+06) and move Kyzylorda oblast
+# probably changed time in territories incorporated into Qostanay oblast
+# (including Arkalyk) from +06/+07 to +05/+06) and move Qyzylorda oblast
 # from being in the fifth time belt and not using decree time into the
-# fourth time belt (no change in practice).[*]
+# fourth time belt (no change in practice).
 #
 # 7. Act of the Government of the Republic of Kazakhstan
 # from 2003-12-29 No. 1342
@@ -1732,7 +1729,7 @@
 # 8. Act of the Government of the Republic of Kazakhstan
 # from 2004-07-20 No. 775
 # http://adilet.zan.kz/rus/archive/docs/P040000775_/20.07.2004
-# modified the 2000-11-23 act to move Kostanay and Kyzylorda oblasts into
+# modified the 2000-11-23 act to move Qostanay and Qyzylorda oblasts into
 # the fifth time belt and add Aktobe oblast to the list of regions not
 # using extra hour ("decree time"), leaving Kazakhstan with only 2 time
 # zones (+04/+05 and +06/+07).  The changes were to be implemented
@@ -1744,14 +1741,14 @@
 # http://adilet.zan.kz/rus/docs/P040001059_
 # modified the 2000-11-23 act to remove exceptions from the "decree time"
 # (leaving Kazakhstan in +05/+06 and +06/+07 zones), amended the
-# 2004-07-20 act to implement changes for Atyrau, West Kazakhstan,
-# Kostanay, Kyzylorda and Mangystau oblasts by not moving clocks
-# during the 2014 transition to "winter" time.
+# 2004-07-20 act to implement changes for Atyraū, West Kazakhstan,
+# Qostanay, Qyzylorda and Mangghystaū oblasts by not moving clocks
+# during the 2004 transition to "winter" time.
 #
-# This means transition from +04/+05 to +05/+06 for Atyrau oblast (no
+# This means transition from +04/+05 to +05/+06 for Atyraū oblast (no
 # zone currently), Asia/Oral, Asia/Aqtau and transition from +05/+06 to
-# +06/+07 for Kostanay oblast (Kostanay and Arkalyk, no zones currently)
-# and Asia/Qyzylorda on 2004-10-31 at 3:00....[*]
+# +06/+07 for Qostanay oblast (Qostanay and Arkalyk, no zones currently)
+# and Asia/Qyzylorda on 2004-10-31 at 3:00....
 #
 # 10. Act of the Government of the Republic of Kazakhstan
 # from 2005-03-15 No. 231
@@ -1767,14 +1764,9 @@
 # Kazakh 1992-01-13 act appears to provide the same rules and 1992-03-27
 # act was to be enacted on the last Sunday of March 1992.
 
-# From Paul Eggert (2016-04-15):
-# The tables below should reflect Stepan Golosunov's remarks above,
-# except for the items marked "[*]" which I haven't gotten to yet.
-# It looks like we will need new zones Asia/Atyrau and Asia/Qostanay
-# to handle changes from 1992 through 2004 that we did not previously
-# know about.
+# From Paul Eggert (2016-11-07):
+# The tables below reflect Golosunov's remarks, with exceptions as noted.
 
-#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
@@ -1787,6 +1779,8 @@
 			6:00 RussiaAsia	+06/+07	2004 Oct 31  2:00s
 			6:00	-	+06
 # Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
+# This currently includes Qostanay (aka Kostanay, Kustanay) (KZ-KUS);
+# see comments below.
 Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
 			5:00	-	+05	1981 Apr  1
@@ -1798,7 +1792,21 @@
 			6:00 RussiaAsia	+06/+07	1992 Mar 29  2:00s
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
 			6:00	-	+06
-# Aqtobe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
+# The following zone is like Asia/Qyzylorda except for being one
+# hour earlier from 1991-09-29 to 1992-03-29.  The 1991/2 rules for
+# Qostenay are unclear partly because of the 1997 Turgai
+# reorganization, so this zone is commented out for now.
+#Zone	Asia/Qostanay	4:14:20 -	LMT	1924 May  2
+#			4:00	-	+04	1930 Jun 21
+#			5:00	-	+05	1981 Apr  1
+#			5:00	1:00	+06	1981 Oct  1
+#			6:00	-	+06	1982 Apr  1
+#			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
+#			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
+#			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
+#			6:00	-	+06
+#
+# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
 Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
 			5:00	-	+05	1981 Apr  1
@@ -1808,14 +1816,11 @@
 			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
 			5:00	-	+05
-# Qostanay (KZ-KUS)
-
-# Mangghystau (KZ-MAN)
+# Mangghystaū (KZ-MAN)
 # Aqtau was not founded until 1963, but it represents an inhabited region,
 # so include time stamps before 1963.
 Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
-			5:00	-	+05	1963
 			5:00	-	+05	1981 Oct  1
 			6:00	-	+06	1982 Apr  1
 			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
@@ -1823,7 +1828,17 @@
 			5:00 RussiaAsia	+05/+06	1994 Sep 25  2:00s
 			4:00 RussiaAsia	+04/+05	2004 Oct 31  2:00s
 			5:00	-	+05
-
+# Atyraū (KZ-ATY) is like Mangghystaū except it switched from
+# +04/+05 to +05/+06 in spring 1999, not fall 1994.
+Zone	Asia/Atyrau	3:27:44	-	LMT	1924 May  2
+			4:00	-	+04	1930 Jun 21
+			5:00	-	+05	1981 Oct  1
+			6:00	-	+06	1982 Apr  1
+			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
+			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
+			5:00 RussiaAsia	+05/+06	1999 Mar 28  2:00s
+			4:00 RussiaAsia	+04/+05	2004 Oct 31  2:00s
+			5:00	-	+05
 # West Kazakhstan (KZ-ZAP)
 # From Paul Eggert (2016-03-18):
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
@@ -2639,7 +2654,7 @@
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
-			2:00	Zion	EET	1948 May 15
+			2:00	Zion	EET/EEST 1948 May 15
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
@@ -2652,7 +2667,7 @@
 			2:00 Palestine	EE%sT
 
 Zone	Asia/Hebron	2:20:23	-	LMT	1900 Oct
-			2:00	Zion	EET	1948 May 15
+			2:00	Zion	EET/EEST 1948 May 15
 			2:00 EgyptAsia	EE%sT	1967 Jun  5
 			2:00	Zion	I%sT	1996
 			2:00	Jordan	EE%sT	1999
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe	Tue Dec 13 02:04:23 2016 +0100
@@ -924,7 +924,7 @@
 # Cyprus
 # Please see the 'asia' file for Asia/Nicosia.
 
-# Czech Republic
+# Czech Republic / Czechia
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
 Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
@@ -2624,10 +2624,9 @@
 			 3:00	-	+03	2016 Mar 27  2:00s
 			 4:00	-	+04
 
-# From Paul Eggert (2016-03-18):
+# From Paul Eggert (2016-11-11):
 # Europe/Volgograd covers:
 # 34	RU-VGG	Volgograd Oblast
-# 64	RU-SAR	Saratov Oblast
 # The 1988 transition is from USSR act No. 5 (1988-01-04).
 
 Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
@@ -2640,6 +2639,27 @@
 			 4:00	-	+04	2014 Oct 26  2:00s
 			 3:00	-	+03
 
+# From Paul Eggert (2016-11-11):
+# Europe/Saratov covers:
+# 64	RU-SAR	Saratov Oblast
+
+# From Yuri Konotopov (2016-11-11):
+# Dec 4, 2016 02:00 UTC+3....  Saratov Region's local time will be ... UTC+4.
+# From Stepan Golosunov (2016-11-11):
+# ... Byalokoz listed Saratov on 03:04:18.
+# From Stepan Golosunov (2016-11-22):
+# http://publication.pravo.gov.ru/Document/View/0001201611220031
+
+Zone Europe/Saratov	 3:04:18 -	LMT	1919 Jul  1  0:00u
+			 3:00	-	+03	1930 Jun 21
+			 4:00	Russia	+04/+05	1988 Mar 27  2:00s
+			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
+			 4:00	-	+04	1992 Mar 29  2:00s
+			 3:00	Russia	+03/+04	2011 Mar 27  2:00s
+			 4:00	-	+04	2014 Oct 26  2:00s
+			 3:00	-	+03	2016 Dec  4  2:00s
+			 4:00	-	+04
+
 # From Paul Eggert (2016-03-18):
 # Europe/Kirov covers:
 # 43	RU-KIR	Kirov Oblast
--- a/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab	Tue Dec 13 02:04:23 2016 +0100
@@ -98,7 +98,7 @@
 CR	Costa Rica
 CU	Cuba
 CV	Cape Verde
-CW	Curacao
+CW	Curaçao
 CX	Christmas Island
 CY	Cyprus
 CZ	Czech Republic
--- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab	Tue Dec 13 02:04:23 2016 +0100
@@ -262,7 +262,8 @@
 KZ	+4315+07657	Asia/Almaty	Kazakhstan (most areas)
 KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda/Kyzylorda/Kzyl-Orda
 KZ	+5017+05710	Asia/Aqtobe	Aqtobe/Aktobe
-KZ	+4431+05016	Asia/Aqtau	Atyrau/Atirau/Gur'yev, Mangghystau/Mankistau
+KZ	+4431+05016	Asia/Aqtau	Mangghystau/Mankistau
+KZ	+4707+05156	Asia/Atyrau	Atyrau/Atirau/Gur'yev
 KZ	+5113+05121	Asia/Oral	West Kazakhstan
 LA	+1758+10236	Asia/Vientiane
 LB	+3353+03530	Asia/Beirut
@@ -353,14 +354,15 @@
 RU	+5443+02030	Europe/Kaliningrad	MSK-01 - Kaliningrad
 RU	+554521+0373704	Europe/Moscow	MSK+00 - Moscow area
 RU	+4457+03406	Europe/Simferopol	MSK+00 - Crimea
-RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd, Saratov
+RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd
 RU	+5836+04939	Europe/Kirov	MSK+00 - Kirov
 RU	+4621+04803	Europe/Astrakhan	MSK+01 - Astrakhan
+RU	+5134+04602	Europe/Saratov	MSK+01 - Saratov
+RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
 RU	+5312+05009	Europe/Samara	MSK+01 - Samara, Udmurtia
-RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
 RU	+5651+06036	Asia/Yekaterinburg	MSK+02 - Urals
 RU	+5500+07324	Asia/Omsk	MSK+03 - Omsk
-RU	+5502+08255	Asia/Novosibirsk	MSK+03 - Novosibirsk
+RU	+5502+08255	Asia/Novosibirsk	MSK+04 - Novosibirsk
 RU	+5322+08345	Asia/Barnaul	MSK+04 - Altai
 RU	+5630+08458	Asia/Tomsk	MSK+04 - Tomsk
 RU	+5345+08707	Asia/Novokuznetsk	MSK+04 - Kemerovo
--- a/jdk/test/tools/jar/compat/CLICompatibility.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/tools/jar/compat/CLICompatibility.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -47,6 +47,7 @@
 
 /*
  * @test
+ * @bug 8170952
  * @library /lib/testlibrary
  * @build jdk.testlibrary.FileUtils jdk.testlibrary.JDKToolFinder
  * @run testng CLICompatibility
@@ -95,7 +96,7 @@
     };
 
     static final FailCheckerWithMessage FAIL_TOO_MANY_MAIN_OPS =
-        new FailCheckerWithMessage("You must specify one of -ctxui options",
+        new FailCheckerWithMessage("You may not specify more than one '-cuxtid' options",
         /* legacy */ "{ctxui}[vfmn0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files");
 
     // Create
@@ -279,11 +280,11 @@
 
     @Test
     public void listBadArgs() {
-        jar("te")
+        jar("tx")
             .assertFailure()
             .resultChecker(FAIL_TOO_MANY_MAIN_OPS);
 
-        jar("-te")
+        jar("-tx")
             .assertFailure()
             .resultChecker(FAIL_TOO_MANY_MAIN_OPS);
 
@@ -344,10 +345,16 @@
             .assertFailure()
             .resultChecker(FAIL_TOO_MANY_MAIN_OPS);
 
-        if (!legacyOnly)
+        if (!legacyOnly) {
             jar("--extract --generate-index")
                 .assertFailure()
+                .resultChecker(new FailCheckerWithMessage(
+                                   "option --generate-index requires an argument"));
+
+            jar("--extract --generate-index=foo")
+                .assertFailure()
                 .resultChecker(FAIL_TOO_MANY_MAIN_OPS);
+        }
     }
 
     @Test
--- a/jdk/test/tools/jlink/CustomPluginTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/tools/jlink/CustomPluginTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -151,6 +151,8 @@
                 .pluginModulePath(pluginModulePath)
                 .output(helper.createNewImageDir(moduleName))
                 .addMods(moduleName)
+                .option("--disable-plugin")
+                .option("release-info")
                 .option("--rogue-filter")
                 .option("/foo/")
                 .call()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/ModuleNamesOrderTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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.
+ */
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.util.Properties;
+import java.util.spi.ToolProvider;
+
+import tests.Helper;
+import tests.JImageGenerator;
+
+/*
+ * @test
+ * @bug 8168925
+ * @summary MODULES property should be topologically ordered and space-separated list
+ * @library ../lib
+ * @build tests.*
+ * @run main ModuleNamesOrderTest
+ */
+public class ModuleNamesOrderTest {
+    static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+        .orElseThrow(() ->
+            new RuntimeException("jlink tool not found")
+        );
+
+    public static void main(String[] args) throws Exception {
+        Helper helper = Helper.newHelper();
+        if (helper == null) {
+            System.err.println("Test not run");
+            return;
+        }
+
+        Path outputDir = helper.createNewImageDir("image8168925");
+        JImageGenerator.getJLinkTask()
+                .modulePath(helper.defaultModulePath())
+                .output(outputDir)
+                .addMods("jdk.scripting.nashorn")
+                .call().assertSuccess();
+
+        File release = new File(outputDir.toString(), "release");
+        if (!release.exists()) {
+            throw new AssertionError("release not generated");
+        }
+
+        Properties props = new Properties();
+        try (FileReader reader = new FileReader(release)) {
+            props.load(reader);
+        }
+
+        String modules = props.getProperty("MODULES");
+        if (!modules.startsWith("\"java.base ")) {
+            throw new AssertionError("MODULES should start with 'java.base'");
+        }
+
+        if (!modules.endsWith(" jdk.scripting.nashorn\"")) {
+            throw new AssertionError("MODULES end with 'jdk.scripting.nashorn'");
+        }
+
+        checkDependency(modules, "java.logging", "java.base");
+        checkDependency(modules, "jdk.dynalink", "java.logging");
+        checkDependency(modules, "java.scripting", "java.base");
+        checkDependency(modules, "jdk.scripting.nashorn", "java.logging");
+        checkDependency(modules, "jdk.scripting.nashorn", "jdk.dynalink");
+        checkDependency(modules, "jdk.scripting.nashorn", "java.scripting");
+    }
+
+    private static void checkDependency(String modules, String fromMod, String toMod) {
+        int fromModIdx = modules.indexOf(fromMod);
+        if (fromModIdx == -1) {
+            throw new AssertionError(fromMod + " is missing in MODULES");
+        }
+        int toModIdx = modules.indexOf(toMod);
+        if (toModIdx == -1) {
+            throw new AssertionError(toMod + " is missing in MODULES");
+        }
+
+        if (toModIdx > fromModIdx) {
+            throw new AssertionError("in MODULES, " + fromMod + " should appear after " + toMod);
+        }
+    }
+}
--- a/jdk/test/tools/jmod/JmodNegativeTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/tools/jmod/JmodNegativeTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -82,7 +82,7 @@
         jmod()
             .assertFailure()
             .resultChecker(r ->
-                assertContains(r.output, "Error: one of create, list, describe, or hash must be specified")
+                assertContains(r.output, "Error: one of create, extract, list, describe, or hash must be specified")
             );
     }
 
@@ -91,7 +91,7 @@
         jmod("badAction")
             .assertFailure()
             .resultChecker(r ->
-                assertContains(r.output, "Error: mode must be one of create, list, describe, or hash")
+                assertContains(r.output, "Error: mode must be one of create, extract, list, describe, or hash")
             );
 
         jmod("--badOption")
--- a/jdk/test/tools/jmod/JmodTest.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/jdk/test/tools/jmod/JmodTest.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8142968
+ * @bug 8142968 8166568
  * @summary Basic test for jmod
  * @library /lib/testlibrary
  * @modules jdk.compiler
@@ -135,6 +135,70 @@
     }
 
     @Test
+    public void testExtractCWD() throws IOException {
+        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
+        jmod("create",
+             "--class-path", cp.toString(),
+             MODS_DIR.resolve("fooExtractCWD.jmod").toString())
+            .assertSuccess();
+
+        jmod("extract",
+             MODS_DIR.resolve("fooExtractCWD.jmod").toString())
+            .assertSuccess()
+            .resultChecker(r -> {
+                // module-info should exist, but jmod will have added its Packages attr.
+                assertTrue(Files.exists(Paths.get("classes/module-info.class")));
+                assertSameContent(cp.resolve("jdk/test/foo/Foo.class"),
+                                  Paths.get("classes/jdk/test/foo/Foo.class"));
+                assertSameContent(cp.resolve("jdk/test/foo/internal/Message.class"),
+                                  Paths.get("classes/jdk/test/foo/internal/Message.class"));
+                assertSameContent(cp.resolve("jdk/test/foo/resources/foo.properties"),
+                                  Paths.get("classes/jdk/test/foo/resources/foo.properties"));
+            });
+    }
+
+    @Test
+    public void testExtractDir() throws IOException {
+        if (Files.exists(Paths.get("extractTestDir")))
+            FileUtils.deleteFileTreeWithRetry(Paths.get("extractTestDir"));
+        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
+        Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
+        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
+        Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");
+
+        jmod("create",
+             "--conf", cf.toString(),
+             "--cmds", bp.toString(),
+             "--libs", lp.toString(),
+             "--class-path", cp.toString(),
+             MODS_DIR.resolve("fooExtractDir.jmod").toString())
+            .assertSuccess();
+
+        jmod("extract",
+             "--dir", "extractTestDir",
+             MODS_DIR.resolve("fooExtractDir.jmod").toString())
+            .assertSuccess();
+
+        jmod("extract",
+             "--dir", "extractTestDir",
+             MODS_DIR.resolve("fooExtractDir.jmod").toString())
+            .assertSuccess()
+            .resultChecker(r -> {
+                // check a sample of the extracted files
+                Path p = Paths.get("extractTestDir");
+                assertTrue(Files.exists(p.resolve("classes/module-info.class")));
+                assertSameContent(cp.resolve("jdk/test/foo/Foo.class"),
+                                  p.resolve("classes/jdk/test/foo/Foo.class"));
+                assertSameContent(bp.resolve("first"),
+                                  p.resolve(CMDS_PREFIX).resolve("first"));
+                assertSameContent(lp.resolve("first.so"),
+                                  p.resolve(LIBS_PREFIX).resolve("second.so"));
+                assertSameContent(cf.resolve("second.cfg"),
+                                  p.resolve(CONFIGS_PREFIX).resolve("second.cfg"));
+            });
+    }
+
+    @Test
     public void testMainClass() throws IOException {
         Path jmod = MODS_DIR.resolve("fooMainClass.jmod");
         FileUtils.deleteFileIfExistsWithRetry(jmod);
@@ -532,6 +596,16 @@
         }
     }
 
+    static void assertSameContent(Path p1, Path p2) {
+        try {
+            byte[] ba1 = Files.readAllBytes(p1);
+            byte[] ba2 = Files.readAllBytes(p2);
+            assertEquals(ba1, ba2);
+        } catch (IOException x) {
+            throw new UncheckedIOException(x);
+        }
+    }
+
     static JmodResult jmod(String... args) {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         PrintStream ps = new PrintStream(baos);
--- a/langtools/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -390,3 +390,4 @@
 cb9e896265ef45295fdd09986dee76624e4d41e4 jdk-9+145
 26f972dc2d174a75bc32131c29661c78568586b0 jdk-9+146
 76389430a13e82a9321cdc085216f6bff526e316 jdk-9+147
+586c93260d3b2f91a055b96118b141c05841694f jdk-9+148
--- a/langtools/src/java.compiler/share/classes/javax/tools/Tool.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/tools/Tool.java	Tue Dec 13 02:04:23 2016 +0100
@@ -45,6 +45,19 @@
  * @since 1.6
  */
 public interface Tool {
+    /**
+     * Returns the name of this tool, or an empty string if no name is provided.
+     *
+     * @apiNote It is recommended that the name be the same as would be
+     * used on the command line: for example, "javac", "jar", "jlink".
+     * @implNote This implementation returns an empty string.
+     *
+     * @return the name of this tool
+     * @since 9
+     */
+    default String name() {
+        return "";
+    }
 
     /**
      * Run the tool with the given I/O channels and arguments. By
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java	Tue Dec 13 02:04:23 2016 +0100
@@ -77,6 +77,12 @@
     @Deprecated
     public JavacTool() {}
 
+    // @Override // can't add @Override until bootstrap JDK provides Tool.name()
+    @DefinedBy(Api.COMPILER)
+    public String name() {
+        return "javac";
+    }
+
     /**
      * Static factory method for creating new instances of this tool.
      * @return new instance of this tool
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Tue Dec 13 02:04:23 2016 +0100
@@ -2218,7 +2218,7 @@
                 return builder.build(rval);
         }
         Name name = TreeInfo.name(rval);
-        if (name == names._super)
+        if (name == names._super || name == names._this)
             return builder.build(rval);
         VarSymbol var =
             new VarSymbol(FINAL|SYNTHETIC,
@@ -3206,7 +3206,11 @@
                                                                       newTag,
                                                                       tree.type,
                                                                       tree.rhs.type);
-                        JCExpression expr = lhs;
+                        //Need to use the "lhs" at two places, once on the future left hand side
+                        //and once in the future binary operator. But further processing may change
+                        //the components of the tree in place (see visitSelect for e.g. <Class>.super.<ident>),
+                        //so cloning the tree to avoid interference between the uses:
+                        JCExpression expr = (JCExpression) lhs.clone();
                         if (expr.type != tree.type)
                             expr = make.TypeCast(tree.type, expr);
                         JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
@@ -3289,9 +3293,14 @@
                             public JCExpression build(final JCExpression tmp2) {
                                 JCTree.Tag opcode = (tree.hasTag(POSTINC))
                                     ? PLUS_ASG : MINUS_ASG;
-                                JCTree lhs = cast
-                                    ? make.TypeCast(tree.arg.type, tmp1)
-                                    : tmp1;
+                                //"tmp1" and "tmp2" may refer to the same instance
+                                //(for e.g. <Class>.super.<ident>). But further processing may
+                                //change the components of the tree in place (see visitSelect),
+                                //so cloning the tree to avoid interference between the two uses:
+                                JCExpression lhs = (JCExpression)tmp1.clone();
+                                lhs = cast
+                                    ? make.TypeCast(tree.arg.type, lhs)
+                                    : lhs;
                                 JCExpression update = makeAssignop(opcode,
                                                              lhs,
                                                              make.Literal(1));
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java	Tue Dec 13 02:04:23 2016 +0100
@@ -499,11 +499,10 @@
     }
 
     boolean isSameFile(PathFileObject other) {
-        try {
-            return Files.isSameFile(path, other.path);
-        } catch (IOException e) {
-            return false;
-        }
+        // By construction, the "path" field should be canonical in all likely, supported scenarios.
+        // (Any exceptions would involve the use of symlinks within a package hierarchy.)
+        // Therefore, it is sufficient to check that the paths are .equals.
+        return path.equals(other.path);
     }
 
     @Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Dec 13 02:04:23 2016 +0100
@@ -2479,7 +2479,7 @@
                     ? parameterNameIndices[index] : 0);
             Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
             paramNames = paramNames.prepend(name);
-            index += Code.width(t);
+            index += sawMethodParameters ? 1 : Code.width(t);
         }
         sym.savedParameterNames = paramNames.reverse();
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -492,6 +492,8 @@
 
 compiler.err.cannot.create.array.with.diamond=''<>''\u3092\u6301\u3064\u914D\u5217\u306F\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093
 
+compiler.err.invalid.module.directive=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30EC\u30AF\u30C6\u30A3\u30D6\u30FB\u30AD\u30FC\u30EF\u30FC\u30C9\u307E\u305F\u306F''}''\u304C\u5FC5\u8981\u3067\u3059
+
 #
 # limits.  We don't give the limits in the diagnostic because we expect
 # them to change, yet we want to use the same diagnostic.  These are all
@@ -841,7 +843,7 @@
 
 ## All errors which do not refer to a particular line in the source code are
 ## preceded by this string.
-compiler.err.error=\u30A8\u30E9\u30FC:
+compiler.err.error=\u30A8\u30E9\u30FC: 
 
 # The following error messages do not refer to a line in the source code.
 compiler.err.cant.read.file={0}\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093
@@ -875,7 +877,7 @@
 compiler.err.locn.module-info.not.allowed.on.patch.path=module-info.class\u306F\u30D1\u30C3\u30C1\u30FB\u30D1\u30B9\u3067\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093: {0}
 
 # 0: string
-compiler.err.locn.invalid.arg.for.xpatch=-Xpatch\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}
+compiler.err.locn.invalid.arg.for.xpatch=--patch-module\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}
 
 #####
 
@@ -944,12 +946,24 @@
 compiler.note.deprecated.plural.additional=\u4E00\u90E8\u306E\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306F\u63A8\u5968\u3055\u308C\u306A\u3044API\u3092\u8FFD\u52A0\u4F7F\u7528\u307E\u305F\u306F\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u3066\u3044\u307E\u3059\u3002
 
 # 0: file name
+compiler.note.removal.filename={0}\u306F\u3001\u524A\u9664\u7528\u306B\u30DE\u30FC\u30AF\u3055\u308C\u305F\u63A8\u5968\u3055\u308C\u306A\u3044API\u3092\u4F7F\u7528\u307E\u305F\u306F\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u3066\u3044\u307E\u3059\u3002
+
+compiler.note.removal.plural=\u4E00\u90E8\u306E\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306F\u3001\u524A\u9664\u7528\u306B\u30DE\u30FC\u30AF\u3055\u308C\u305F\u63A8\u5968\u3055\u308C\u306A\u3044API\u3092\u4F7F\u7528\u307E\u305F\u306F\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u3066\u3044\u307E\u3059\u3002
+
+# The following string may appear after one of the above removal messages.
+compiler.note.removal.recompile=\u8A73\u7D30\u306F\u3001-Xlint:removal\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3057\u3066\u518D\u30B3\u30F3\u30D1\u30A4\u30EB\u3057\u3066\u304F\u3060\u3055\u3044\u3002
+
+# 0: file name
+compiler.note.removal.filename.additional={0}\u306B\u3001\u524A\u9664\u7528\u306B\u30DE\u30FC\u30AF\u3055\u308C\u305F\u63A8\u5968\u3055\u308C\u306A\u3044API\u306E\u8FFD\u52A0\u4F7F\u7528\u307E\u305F\u306F\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u304C\u3042\u308A\u307E\u3059\u3002
+
+compiler.note.removal.plural.additional=\u4E00\u90E8\u306E\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306F\u3001\u524A\u9664\u7528\u306B\u30DE\u30FC\u30AF\u3055\u308C\u305F\u63A8\u5968\u3055\u308C\u306A\u3044API\u3092\u8FFD\u52A0\u4F7F\u7528\u307E\u305F\u306F\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u3066\u3044\u307E\u3059\u3002
+
+# 0: file name
 compiler.note.unchecked.filename={0}\u306E\u64CD\u4F5C\u306F\u3001\u672A\u30C1\u30A7\u30C3\u30AF\u307E\u305F\u306F\u5B89\u5168\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
 
 compiler.note.unchecked.plural=\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u64CD\u4F5C\u306E\u3046\u3061\u3001\u672A\u30C1\u30A7\u30C3\u30AF\u307E\u305F\u306F\u5B89\u5168\u3067\u306F\u306A\u3044\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002
 
-# The following string may appear after one of the above deprecation
-# messages.
+# The following string may appear after one of the above unchecked messages.
 compiler.note.unchecked.recompile=\u8A73\u7D30\u306F\u3001-Xlint:unchecked\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3057\u3066\u518D\u30B3\u30F3\u30D1\u30A4\u30EB\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 
 # 0: file name
@@ -1021,7 +1035,7 @@
 ## Warning messages may also include the following prefix to identify a
 ## lint option
 # 0: option name
-compiler.warn.lintOption=[{0}]
+compiler.warn.lintOption=[{0}] 
 
 # 0: symbol
 compiler.warn.constant.SVUID=serialVersionUID\u306F\u30AF\u30E9\u30B9{0}\u306E\u5B9A\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
@@ -1037,6 +1051,9 @@
 # 0: symbol, 1: symbol
 compiler.warn.has.been.deprecated={1}\u306E{0}\u306F\u63A8\u5968\u3055\u308C\u307E\u305B\u3093
 
+# 0: symbol, 1: symbol
+compiler.warn.has.been.deprecated.for.removal={1}\u306E{0}\u306F\u63A8\u5968\u3055\u308C\u3066\u304A\u3089\u305A\u3001\u524A\u9664\u7528\u306B\u30DE\u30FC\u30AF\u3055\u308C\u3066\u3044\u307E\u3059
+
 # 0: symbol
 compiler.warn.sun.proprietary={0}\u306F\u5185\u90E8\u6240\u6709\u306EAPI\u3067\u3042\u308A\u3001\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
 
@@ -1190,10 +1207,16 @@
 
 compiler.warn.missing.deprecated.annotation=\u63A8\u5968\u3055\u308C\u306A\u3044\u9805\u76EE\u306F@Deprecated\u3067\u6CE8\u91C8\u304C\u4ED8\u3051\u3089\u308C\u3066\u3044\u307E\u305B\u3093
 
+# 0: symbol kind
+compiler.warn.deprecated.annotation.has.no.effect=@Deprecated\u6CE8\u91C8\u306F\u3001\u3053\u306E{0}\u5BA3\u8A00\u306B\u306F\u5F71\u97FF\u3057\u307E\u305B\u3093
+
 compiler.warn.invalid.archive.file=\u30D1\u30B9\u4E0A\u306E\u4E88\u671F\u3057\u306A\u3044\u30D5\u30A1\u30A4\u30EB: {0}
 
 compiler.warn.unexpected.archive.file=\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u4E88\u671F\u3057\u306A\u3044\u62E1\u5F35\u5B50: {0}
 
+# 0: path
+compiler.err.no.zipfs.for.archive=\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u306E\u51E6\u7406\u306B\u4F7F\u7528\u3067\u304D\u308B\u30D5\u30A1\u30A4\u30EB\u30FB\u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u304C\u3042\u308A\u307E\u305B\u3093: {0}
+
 compiler.warn.div.zero=\u30BC\u30ED\u3067\u9664\u7B97
 
 compiler.warn.empty.if=if\u4EE5\u964D\u304C\u7A7A\u306E\u6587\u3067\u3059
@@ -1222,7 +1245,10 @@
 compiler.warn.varargs.redundant.trustme.anno={0}\u6CE8\u91C8\u304C\u5197\u9577\u3067\u3059\u3002{1}
 
 # 0: symbol
-compiler.warn.access.to.sensitive.member.from.serializable.element=\u76F4\u5217\u5316\u53EF\u80FD\u8981\u7D20\u304B\u3089\u6A5F\u5BC6\u30E1\u30F3\u30D0\u30FC{0}\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306F\u3001\u4FE1\u983C\u3067\u304D\u306A\u3044\u30B3\u30FC\u30C9\u304B\u3089\u30D1\u30D6\u30EA\u30C3\u30AF\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3042\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
+compiler.warn.access.to.member.from.serializable.element=\u76F4\u5217\u5316\u53EF\u80FD\u8981\u7D20\u304B\u3089\u30E1\u30F3\u30D0\u30FC{0}\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306F\u3001\u4FE1\u983C\u3067\u304D\u306A\u3044\u30B3\u30FC\u30C9\u304B\u3089\u30D1\u30D6\u30EA\u30C3\u30AF\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3042\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
+
+# 0: symbol
+compiler.warn.access.to.member.from.serializable.lambda=\u76F4\u5217\u5316\u53EF\u80FD\u30E9\u30E0\u30C0\u304B\u3089\u30E1\u30F3\u30D0\u30FC{0}\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306F\u3001\u4FE1\u983C\u3067\u304D\u306A\u3044\u30B3\u30FC\u30C9\u304B\u3089\u30D1\u30D6\u30EA\u30C3\u30AF\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3042\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
 
 #####
 
@@ -1338,6 +1364,9 @@
 # 0: string (classfile major version), 1: string (classfile minor version)
 compiler.misc.invalid.static.interface=\u30D0\u30FC\u30B8\u30E7\u30F3{0}.{1}\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306Bstatic\u30E1\u30BD\u30C3\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F
 
+# 0: string (classfile major version), 1: string (classfile minor version)
+compiler.misc.anachronistic.module.info=\u30D0\u30FC\u30B8\u30E7\u30F3{0}.{1}\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F
+
 # 0: name
 compiler.misc.file.doesnt.contain.class=\u30D5\u30A1\u30A4\u30EB\u306B\u30AF\u30E9\u30B9{0}\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u305B\u3093
 
@@ -1950,15 +1979,18 @@
 # 0: name, 1: name
 compiler.err.module.name.mismatch=\u30E2\u30B8\u30E5\u30FC\u30EB\u540D{0}\u306F\u5FC5\u8981\u306A\u540D\u524D{1}\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093
 
+# 0: name, 1: name
+compiler.misc.module.name.mismatch=\u30E2\u30B8\u30E5\u30FC\u30EB\u540D{0}\u306F\u5FC5\u8981\u306A\u540D\u524D{1}\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093
+
 compiler.err.module.decl.sb.in.module-info.java=\u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306Fmodule-info.java\u3068\u3044\u3046\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u306B\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
 
 compiler.err.module-info.with.xmodule.sourcepath=\u30BD\u30FC\u30B9\u30D1\u30B9\u306E-Xmodule\u3068module-info\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059
 
 compiler.err.module-info.with.xmodule.classpath=\u30AF\u30E9\u30B9\u30D1\u30B9\u306E-Xmodule\u3068module-info\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059
 
-compiler.err.xmodule.no.module.sourcepath=-Xmodule\u3068-modulesourcepath\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059
-
-compiler.err.processorpath.no.processormodulepath=-processorpath\u3068-processormodulepath\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059
+compiler.err.xmodule.no.module.sourcepath=-Xmodule\u3068--module-source-path\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059
+
+compiler.err.processorpath.no.processormodulepath=-processorpath\u3068--processor-module-path\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059
 
 # 0: symbol
 compiler.err.package.in.other.module=\u30D1\u30C3\u30B1\u30FC\u30B8\u304C\u5225\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u5B58\u5728\u3057\u307E\u3059: {0}
@@ -1983,18 +2015,18 @@
 compiler.err.duplicate.module.on.path={0}\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059\n{1}\u306E\u30E2\u30B8\u30E5\u30FC\u30EB
 
 # 0:  string
-compiler.err.xaddexports.malformed.entry=-XaddExports\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059: {0}
+compiler.err.xaddexports.malformed.entry=--add-exports {0}\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059
 
 # 0: string
-compiler.err.xaddexports.too.many={0}\u306E-XaddExports\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8907\u6570\u3042\u308A\u307E\u3059
+compiler.err.xaddexports.too.many={0}\u306E--add-exports\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8907\u6570\u3042\u308A\u307E\u3059
 
 # 0:  string
-compiler.err.xaddreads.malformed.entry=-XaddReads\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059: {0}
+compiler.err.xaddreads.malformed.entry=--add-reads {0}\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059
 
 # 0: string
-compiler.err.xaddreads.too.many={0}\u306E-XaddReads\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8907\u6570\u3042\u308A\u307E\u3059
-
-compiler.err.addmods.all.module.path.invalid=-addmods ALL-MODULE-PATH\u306F\u3001\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059
+compiler.err.xaddreads.too.many={0}\u306E--add-reads\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8907\u6570\u3042\u308A\u307E\u3059
+
+compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH\u306F\u3001\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059
 
 compiler.misc.locn.module_source_path=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30BD\u30FC\u30B9\u30FB\u30D1\u30B9
 
@@ -2015,6 +2047,15 @@
 # 0: symbol
 compiler.warn.service.provided.but.not.exported.or.used=\u30B5\u30FC\u30D3\u30B9\u30FB\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F\u304C\u3001\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u307E\u305F\u306F\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible=\u30E2\u30B8\u30E5\u30FC\u30EB{2}\u306E{0} {1}\u306F\u3001\u3053\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304B\u3089\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible.unexported=\u30E2\u30B8\u30E5\u30FC\u30EB{2}\u306E{0} {1}\u306F\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3055\u308C\u307E\u305B\u3093
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible.not.required.public=\u30E2\u30B8\u30E5\u30FC\u30EB{2}\u306E{0} {1}\u306F\u3001''requires public''\u3092\u4F7F\u7528\u3057\u3066\u9593\u63A5\u7684\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3055\u308C\u307E\u305B\u3093
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible.unexported.qualified=\u30E2\u30B8\u30E5\u30FC\u30EB{2}\u306E{0} {1}\u306F\u3001\u3053\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u3059\u3079\u3066\u306E\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u306B\u8868\u793A\u3055\u308C\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
+
 ###
 # errors related to options
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -492,6 +492,8 @@
 
 compiler.err.cannot.create.array.with.diamond=\u65E0\u6CD5\u521B\u5EFA\u5177\u6709 ''<>'' \u7684\u6570\u7EC4
 
+compiler.err.invalid.module.directive=\u9884\u671F\u4E3A\u6A21\u5757\u6307\u4EE4\u5173\u952E\u5B57\u6216 ''}''
+
 #
 # limits.  We don't give the limits in the diagnostic because we expect
 # them to change, yet we want to use the same diagnostic.  These are all
@@ -841,7 +843,7 @@
 
 ## All errors which do not refer to a particular line in the source code are
 ## preceded by this string.
-compiler.err.error=\u9519\u8BEF:
+compiler.err.error=\u9519\u8BEF: 
 
 # The following error messages do not refer to a line in the source code.
 compiler.err.cant.read.file=\u65E0\u6CD5\u8BFB\u53D6: {0}
@@ -875,7 +877,7 @@
 compiler.err.locn.module-info.not.allowed.on.patch.path=\u5728\u8865\u4E01\u7A0B\u5E8F\u8DEF\u5F84\u4E2D\u4E0D\u5141\u8BB8 module-info.class: {0}
 
 # 0: string
-compiler.err.locn.invalid.arg.for.xpatch=-Xpatch \u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}
+compiler.err.locn.invalid.arg.for.xpatch=--patch-module \u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}
 
 #####
 
@@ -927,7 +929,7 @@
 # 0: boolean, 1: symbol
 compiler.note.mref.stat.1=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metafactory = {0}\nbridge \u65B9\u6CD5 = {1}
 
-compiler.note.note=\u6CE8:
+compiler.note.note=\u6CE8: 
 
 # 0: file name
 compiler.note.deprecated.filename={0}\u4F7F\u7528\u6216\u8986\u76D6\u4E86\u5DF2\u8FC7\u65F6\u7684 API\u3002
@@ -944,12 +946,24 @@
 compiler.note.deprecated.plural.additional=\u67D0\u4E9B\u8F93\u5165\u6587\u4EF6\u8FD8\u4F7F\u7528\u6216\u8986\u76D6\u4E86\u5DF2\u8FC7\u65F6\u7684 API\u3002
 
 # 0: file name
+compiler.note.removal.filename={0} \u4F7F\u7528\u6216\u8986\u76D6\u4E86\u6807\u8BB0\u4E3A\u5F85\u5220\u9664\u7684\u5DF2\u8FC7\u65F6 API\u3002
+
+compiler.note.removal.plural=\u67D0\u4E9B\u8F93\u5165\u6587\u4EF6\u4F7F\u7528\u6216\u8986\u76D6\u4E86\u6807\u8BB0\u4E3A\u5F85\u5220\u9664\u7684\u5DF2\u8FC7\u65F6 API\u3002
+
+# The following string may appear after one of the above removal messages.
+compiler.note.removal.recompile=\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u4F7F\u7528 -Xlint:removal \u91CD\u65B0\u7F16\u8BD1\u3002
+
+# 0: file name
+compiler.note.removal.filename.additional={0} \u989D\u5916\u4F7F\u7528\u6216\u8986\u76D6\u4E86\u6807\u8BB0\u4E3A\u5F85\u5220\u9664\u7684\u5DF2\u8FC7\u65F6 API\u3002
+
+compiler.note.removal.plural.additional=\u67D0\u4E9B\u8F93\u5165\u6587\u4EF6\u989D\u5916\u4F7F\u7528\u6216\u8986\u76D6\u4E86\u6807\u8BB0\u4E3A\u5F85\u5220\u9664\u7684\u5DF2\u8FC7\u65F6 API\u3002
+
+# 0: file name
 compiler.note.unchecked.filename={0}\u4F7F\u7528\u4E86\u672A\u7ECF\u68C0\u67E5\u6216\u4E0D\u5B89\u5168\u7684\u64CD\u4F5C\u3002
 
 compiler.note.unchecked.plural=\u67D0\u4E9B\u8F93\u5165\u6587\u4EF6\u4F7F\u7528\u4E86\u672A\u7ECF\u68C0\u67E5\u6216\u4E0D\u5B89\u5168\u7684\u64CD\u4F5C\u3002
 
-# The following string may appear after one of the above deprecation
-# messages.
+# The following string may appear after one of the above unchecked messages.
 compiler.note.unchecked.recompile=\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u4F7F\u7528 -Xlint:unchecked \u91CD\u65B0\u7F16\u8BD1\u3002
 
 # 0: file name
@@ -1016,12 +1030,12 @@
 ##
 
 ## All warning messages are preceded by the following string.
-compiler.warn.warning=\u8B66\u544A:
+compiler.warn.warning=\u8B66\u544A: 
 
 ## Warning messages may also include the following prefix to identify a
 ## lint option
 # 0: option name
-compiler.warn.lintOption=[{0}]
+compiler.warn.lintOption=[{0}] 
 
 # 0: symbol
 compiler.warn.constant.SVUID=serialVersionUID \u5728\u7C7B{0}\u4E2D\u5FC5\u987B\u662F\u5E38\u91CF
@@ -1037,6 +1051,9 @@
 # 0: symbol, 1: symbol
 compiler.warn.has.been.deprecated={1}\u4E2D\u7684{0}\u5DF2\u8FC7\u65F6
 
+# 0: symbol, 1: symbol
+compiler.warn.has.been.deprecated.for.removal={1} \u4E2D\u7684 {0} \u5DF2\u8FC7\u65F6, \u4E14\u6807\u8BB0\u4E3A\u5F85\u5220\u9664
+
 # 0: symbol
 compiler.warn.sun.proprietary={0}\u662F\u5185\u90E8\u4E13\u7528 API, \u53EF\u80FD\u4F1A\u5728\u672A\u6765\u53D1\u884C\u7248\u4E2D\u5220\u9664
 
@@ -1190,10 +1207,16 @@
 
 compiler.warn.missing.deprecated.annotation=\u672A\u4F7F\u7528 @Deprecated \u5BF9\u5DF2\u8FC7\u65F6\u7684\u9879\u76EE\u8FDB\u884C\u6CE8\u91CA
 
+# 0: symbol kind
+compiler.warn.deprecated.annotation.has.no.effect=@Deprecated \u6CE8\u91CA\u5BF9\u6B64 {0} \u58F0\u660E\u6CA1\u6709\u4EFB\u4F55\u6548\u679C
+
 compiler.warn.invalid.archive.file=\u4EE5\u4E0B\u8DEF\u5F84\u4E2D\u5B58\u5728\u610F\u5916\u7684\u6587\u4EF6: {0}
 
 compiler.warn.unexpected.archive.file=\u4EE5\u4E0B\u6863\u6848\u6587\u4EF6\u5B58\u5728\u610F\u5916\u7684\u6269\u5C55\u540D: {0}
 
+# 0: path
+compiler.err.no.zipfs.for.archive=\u6CA1\u6709\u4EFB\u4F55\u6587\u4EF6\u7CFB\u7EDF\u63D0\u4F9B\u65B9\u53EF\u5904\u7406\u6B64\u6587\u4EF6: {0}
+
 compiler.warn.div.zero=\u9664\u6570\u4E3A\u96F6
 
 compiler.warn.empty.if=if \u4E4B\u540E\u6CA1\u6709\u8BED\u53E5
@@ -1222,7 +1245,10 @@
 compiler.warn.varargs.redundant.trustme.anno=\u5197\u4F59\u7684 {0} \u6CE8\u91CA\u3002{1}
 
 # 0: symbol
-compiler.warn.access.to.sensitive.member.from.serializable.element=\u53EF\u4E32\u884C\u5316\u5143\u7D20\u5BF9\u654F\u611F\u6210\u5458 {0} \u7684\u8BBF\u95EE\u53EF\u4EE5\u7531\u4E0D\u53D7\u4FE1\u4EFB\u7684\u4EE3\u7801\u516C\u5F00\u6267\u884C
+compiler.warn.access.to.member.from.serializable.element=\u53EF\u4E32\u884C\u5316\u5143\u7D20\u5BF9\u6210\u5458 {0} \u7684\u8BBF\u95EE\u53EF\u4EE5\u7531\u4E0D\u53D7\u4FE1\u4EFB\u7684\u4EE3\u7801\u516C\u5F00\u6267\u884C
+
+# 0: symbol
+compiler.warn.access.to.member.from.serializable.lambda=\u53EF\u4E32\u884C\u5316 lambda \u5BF9\u6210\u5458 {0} \u7684\u8BBF\u95EE\u53EF\u4EE5\u7531\u4E0D\u53D7\u4FE1\u4EFB\u7684\u4EE3\u7801\u516C\u5F00\u6267\u884C
 
 #####
 
@@ -1338,6 +1364,9 @@
 # 0: string (classfile major version), 1: string (classfile minor version)
 compiler.misc.invalid.static.interface=\u5728 {0}.{1} \u7248\u7C7B\u6587\u4EF6\u4E2D\u627E\u5230\u9759\u6001\u65B9\u6CD5
 
+# 0: string (classfile major version), 1: string (classfile minor version)
+compiler.misc.anachronistic.module.info=\u5728 {0}.{1} \u7248\u7C7B\u6587\u4EF6\u4E2D\u627E\u5230\u6A21\u5757\u58F0\u660E
+
 # 0: name
 compiler.misc.file.doesnt.contain.class=\u6587\u4EF6\u4E0D\u5305\u542B\u7C7B{0}
 
@@ -1950,15 +1979,18 @@
 # 0: name, 1: name
 compiler.err.module.name.mismatch=\u6A21\u5757\u540D\u79F0 {0} \u4E0E\u9884\u671F\u540D\u79F0 {1} \u4E0D\u5339\u914D
 
+# 0: name, 1: name
+compiler.misc.module.name.mismatch=\u6A21\u5757\u540D\u79F0 {0} \u4E0E\u9884\u671F\u540D\u79F0 {1} \u4E0D\u5339\u914D
+
 compiler.err.module.decl.sb.in.module-info.java=\u6A21\u5757\u58F0\u660E\u5E94\u8BE5\u5728\u540D\u4E3A module-info.java \u7684\u6587\u4EF6\u4E2D
 
 compiler.err.module-info.with.xmodule.sourcepath=\u6E90\u8DEF\u5F84\u4E0A\u7684 -Xmodule \u4E0E module-info \u7684\u7EC4\u5408\u975E\u6CD5
 
 compiler.err.module-info.with.xmodule.classpath=\u7C7B\u8DEF\u5F84\u4E0A\u7684 -Xmodule \u4E0E module-info \u7684\u7EC4\u5408\u975E\u6CD5
 
-compiler.err.xmodule.no.module.sourcepath=-Xmodule \u4E0E -modulesourcepath \u7684\u7EC4\u5408\u975E\u6CD5
-
-compiler.err.processorpath.no.processormodulepath=-processorpath \u4E0E -processormodulepath \u7684\u7EC4\u5408\u975E\u6CD5
+compiler.err.xmodule.no.module.sourcepath=-Xmodule \u4E0E --module-source-path \u7684\u7EC4\u5408\u975E\u6CD5
+
+compiler.err.processorpath.no.processormodulepath=-processorpath \u4E0E --processor-module-path \u7684\u7EC4\u5408\u975E\u6CD5
 
 # 0: symbol
 compiler.err.package.in.other.module=\u7A0B\u5E8F\u5305\u5DF2\u5B58\u5728\u4E8E\u53E6\u4E00\u4E2A\u6A21\u5757\u4E2D: {0}
@@ -1983,18 +2015,18 @@
 compiler.err.duplicate.module.on.path={1} \u4E2D\u7684 {0} \u4E0A\u5B58\u5728\n\u91CD\u590D\u7684\u6A21\u5757
 
 # 0:  string
-compiler.err.xaddexports.malformed.entry=-XaddExports \u7684\u503C\u9519\u8BEF: {0}
+compiler.err.xaddexports.malformed.entry=--add-exports {0} \u7684\u503C\u9519\u8BEF
 
 # 0: string
-compiler.err.xaddexports.too.many={0} \u5B58\u5728\u591A\u4E2A -XaddExports \u9009\u9879
+compiler.err.xaddexports.too.many={0} \u5B58\u5728\u591A\u4E2A --add-exports \u9009\u9879
 
 # 0:  string
-compiler.err.xaddreads.malformed.entry=-XaddReads \u7684\u503C\u9519\u8BEF: {0}
+compiler.err.xaddreads.malformed.entry=--add-reads {0} \u7684\u503C\u9519\u8BEF
 
 # 0: string
-compiler.err.xaddreads.too.many={0} \u5B58\u5728\u591A\u4E2A -XaddReads \u9009\u9879
-
-compiler.err.addmods.all.module.path.invalid=-addmods ALL-MODULE-PATH \u53EA\u80FD\u5728\u7F16\u8BD1\u672A\u547D\u540D\u6A21\u5757\u65F6\u4F7F\u7528
+compiler.err.xaddreads.too.many={0} \u5B58\u5728\u591A\u4E2A --add-reads \u9009\u9879
+
+compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH \u53EA\u80FD\u5728\u7F16\u8BD1\u672A\u547D\u540D\u6A21\u5757\u65F6\u4F7F\u7528
 
 compiler.misc.locn.module_source_path=\u6A21\u5757\u6E90\u8DEF\u5F84
 
@@ -2015,6 +2047,15 @@
 # 0: symbol
 compiler.warn.service.provided.but.not.exported.or.used=\u5DF2\u63D0\u4F9B\u670D\u52A1\u63A5\u53E3, \u4F46\u672A\u5BFC\u51FA\u6216\u4F7F\u7528\u670D\u52A1\u63A5\u53E3
 
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible=\u6A21\u5757 {2} \u4E2D\u7684 {0} {1} \u5BF9\u9700\u8981\u8BE5\u6A21\u5757\u7684\u5BA2\u6237\u673A\u4E0D\u53EF\u8BBF\u95EE
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible.unexported=\u672A\u5BFC\u51FA\u6A21\u5757 {2} \u4E2D\u7684 {0} {1}
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible.not.required.public=\u672A\u4F7F\u7528 ''requires public'' \u95F4\u63A5\u5BFC\u51FA\u6A21\u5757 {2} \u4E2D\u7684 {0} {1}
+# 0: kind name, 1: symbol, 2: symbol
+compiler.warn.leaks.not.accessible.unexported.qualified=\u6A21\u5757 {2} \u4E2D\u7684 {0} {1} \u53EF\u80FD\u5BF9\u9700\u8981\u8BE5\u6A21\u5757\u7684\u6240\u6709\u5BA2\u6237\u673A\u90FD\u4E0D\u53EF\u89C1
+
 ###
 # errors related to options
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -97,8 +97,8 @@
 javac.opt.Xlint.all=\u3059\u3079\u3066\u306E\u8B66\u544A\u3092\u6709\u52B9\u306B\u3057\u307E\u3059
 javac.opt.Xlint.none=\u3059\u3079\u3066\u306E\u8B66\u544A\u3092\u7121\u52B9\u306B\u3057\u307E\u3059
 #L10N: do not localize: -Xlint
-javac.opt.Xlint.subopts=-Xlint:key,...
-javac.opt.Xlint.suboptlist=\n        \u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3059\u308B\u8B66\u544A(\u30AB\u30F3\u30DE\u533A\u5207\u308A)\u3002\n        \u6307\u5B9A\u3057\u305F\u8B66\u544A\u3092\u7121\u52B9\u306B\u3059\u308B\u306B\u306F\u3001\u30AD\u30FC\u306E\u524D\u306B'-'\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n        \u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30AD\u30FC\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:
+javac.opt.arg.Xlint=<key>(,<key>)*
+javac.opt.Xlint.custom=\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3059\u308B\u8B66\u544A(\u30AB\u30F3\u30DE\u533A\u5207\u308A)\u3002\n        \u6307\u5B9A\u3057\u305F\u8B66\u544A\u3092\u7121\u52B9\u306B\u3059\u308B\u306B\u306F\u3001\u30AD\u30FC\u306E\u524D\u306B'-'\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n        \u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30AD\u30FC\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:
 javac.opt.Xlint.desc.auxiliaryclass=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3067\u975E\u8868\u793A\u306B\u306A\u3063\u3066\u3044\u308B\u304C\u4ED6\u306E\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u88DC\u52A9\u30AF\u30E9\u30B9\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
 
 javac.opt.Xlint.desc.cast=\u4E0D\u8981\u306A\u30AD\u30E3\u30B9\u30C8\u306E\u4F7F\u7528\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
@@ -113,6 +113,8 @@
 
 javac.opt.Xlint.desc.empty=if\u4EE5\u964D\u304C\u7A7A\u306E\u6587\u3067\u3042\u308B\u3053\u3068\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
 
+javac.opt.Xlint.desc.exports=\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u306B\u95A2\u3059\u308B\u554F\u984C\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
+
 javac.opt.Xlint.desc.fallthrough=switch\u6587\u306E1\u3064\u306Ecase\u304B\u3089\u6B21\u3078\u306E\u30D5\u30A9\u30FC\u30EB\u30FB\u30B9\u30EB\u30FC\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
 
 javac.opt.Xlint.desc.finally=\u6B63\u5E38\u306B\u5B8C\u4E86\u3057\u306A\u3044finally\u7BC0\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
@@ -129,7 +131,9 @@
 
 javac.opt.Xlint.desc.rawtypes=raw\u578B\u306E\u4F7F\u7528\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
 
-javac.opt.Xlint.desc.serial=\u30B7\u30EA\u30A2\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3ID\u3092\u6307\u5B9A\u3057\u306A\u3044\u76F4\u5217\u5316\u53EF\u80FD\u306A\u30AF\u30E9\u30B9\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
+javac.opt.Xlint.desc.removal=\u524A\u9664\u7528\u306B\u30DE\u30FC\u30AF\u3055\u308C\u305FAPI\u306E\u4F7F\u7528\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
+
+javac.opt.Xlint.desc.serial=\u30B7\u30EA\u30A2\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3ID\u3092\u6307\u5B9A\u3057\u306A\u3044\u76F4\u5217\u5316\u53EF\u80FD\u306A\u30AF\u30E9\u30B9\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002 \n                             \u307E\u305F\u3001\u76F4\u5217\u5316\u53EF\u80FD\u8981\u7D20\u304B\u3089public\u4EE5\u5916\u306E\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
 
 javac.opt.Xlint.desc.static=\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u4F7F\u7528\u3057\u305Fstatic\u30E1\u30F3\u30D0\u30FC\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306B\u3064\u3044\u3066\u8B66\u544A\u3057\u307E\u3059\u3002
 
@@ -145,11 +149,11 @@
 
 # L10N: do not localize: accessibility html missing reference syntax
 # L10N: do not localize: public protected package private
-javac.opt.Xdoclint.custom=\n        javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n        \u3053\u3053\u3067\u3001<group>\u306Faccessibility\u3001html\u3001missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3001\n        <access>\u306Fpublic\u3001protected\u3001package\u307E\u305F\u306Fprivate\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002
+javac.opt.Xdoclint.custom=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n        \u3053\u3053\u3067\u3001<group>\u306Faccessibility\u3001html\u3001missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3001\n        <access>\u306Fpublic\u3001protected\u3001package\u307E\u305F\u306Fprivate\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002
 
-javac.opt.Xdoclint.package.args = ([-]<packages>)
+javac.opt.Xdoclint.package.args = [-]<packages>(,[-]<package>)*
 
-javac.opt.Xdoclint.package.desc=\n        \u7279\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002<packages>\u306F\n        \u30AB\u30F3\u30DE\u3067\u533A\u5207\u3089\u308C\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306F\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\n        \u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u3001\u307E\u305F\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306E\u63A5\u982D\u8F9E\u306E\u5F8C\u306B''.*''\u3092\u6307\u5B9A(\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\n        \u3059\u3079\u3066\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u62E1\u5F35)\u3057\u305F\u3082\u306E\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u524D\u306B'-'\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\n        \u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u95A2\u3059\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u7121\u52B9\u306B\u3067\u304D\u307E\u3059\u3002
+javac.opt.Xdoclint.package.desc=\u7279\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\u5404<package>\u306F\u3001\n\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u3001\u307E\u305F\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306E\u63A5\u982D\u8F9E\u306E\u5F8C\u306B''.*''\u3092\u6307\u5B9A\n(\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u3059\u3079\u3066\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u62E1\u5F35)\u3057\u305F\u3082\u306E\u3067\u3059\u3002\u5404<package>\u306E\u524D\u306B\n'-'\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u6307\u5B9A\u3057\u305F1\u3064\u4EE5\u4E0A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u95A2\u3059\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u7121\u52B9\u306B\u3067\u304D\u307E\u3059\u3002
 
 javac.opt.Xstdout=\u6A19\u6E96\u51FA\u529B\u3092\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3059\u308B
 javac.opt.X=\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B
@@ -161,18 +165,19 @@
 javac.opt.prefer=\u6697\u9ED9\u7684\u306B\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u306B\u3064\u3044\u3066\u3001\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3068\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u4E21\u65B9\u304C\u898B\u3064\u304B\u3063\u305F\u969B\u3069\u3061\u3089\u3092\u8AAD\u307F\u8FBC\u3080\u304B\u6307\u5B9A\u3059\u308B
 javac.opt.AT=\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u306E\u8AAD\u53D6\u308A\u30AA\u30D7\u30B7\u30E7\u30F3\u304A\u3088\u3073\u30D5\u30A1\u30A4\u30EB\u540D
 javac.opt.diags=\u8A3A\u65AD\u30E2\u30FC\u30C9\u306E\u9078\u629E
-javac.opt.addExports=\n        <other-module>\u304CALL-UNNAMED\u3067\u3042\u308B\u5834\u5408\u3001\u305D\u306E\u5B9A\u7FA9\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\u3001\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u307E\u305F\u306F\n        \u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u6E08\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002
+javac.opt.addExports=<other-module>\u304CALL-UNNAMED\u3067\u3042\u308B\u5834\u5408\u3001\u305D\u306E\u5B9A\u7FA9\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\u3001\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u307E\u305F\u306F\n        \u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u6E08\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002
 javac.opt.arg.addExports=<module>/<package>=<other-module>(,<other-module>)*
-javac.opt.addReads=\n        \u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u5FC5\u9808\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n        \u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u5834\u5408\u3001<other-module>\u306FALL-UNNAMED\u306B\u3057\u307E\u3059\u3002
+javac.opt.addReads=\u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u5FC5\u9808\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n        \u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u5834\u5408\u3001<other-module>\u306FALL-UNNAMED\u306B\u3057\u307E\u3059\u3002
 javac.opt.arg.addReads=<module>=<other-module>(,<other-module>)*
-javac.opt.patch=\n        JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n        \u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3057\u307E\u3059
+javac.opt.patch=JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n        \u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3057\u307E\u3059
 javac.opt.arg.patch=<module>=<file>(:<file>)*
 javac.opt.module=\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u304C\u5C5E\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002
-javac.opt.arg.module=<module-name>
-javac.opt.addmods=\n        \u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F<module>\u304C\n        ALL-MODULE-PATH\u3067\u3042\u308B\u5834\u5408\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3002
+javac.opt.arg.module=<module>
+javac.opt.addmods=\u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F<module>\u304C\n        ALL-MODULE-PATH\u3067\u3042\u308B\u5834\u5408\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3002
 javac.opt.arg.addmods=<module>(,<module>)*
-javac.opt.limitmods=\u76E3\u8996\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30E6\u30CB\u30D0\u30FC\u30B9\u3092\u5236\u9650\u3057\u307E\u3059
+javac.opt.limitmods=\u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3057\u307E\u3059
 javac.opt.arg.limitmods=<module>(,<module>)*
+javac.opt.inherit_runtime_environment=\u5B9F\u884C\u6642\u74B0\u5883\u304B\u3089\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30B7\u30B9\u30C6\u30E0\u69CB\u6210\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u7D99\u627F\u3057\u307E\u3059\u3002
 
 ## errors
 
@@ -190,19 +195,20 @@
 javac.err.req.arg={0}\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3059
 javac.err.invalid.source={0}\u306F\u7121\u52B9\u306A\u30BD\u30FC\u30B9\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u3059
 javac.err.error.writing.file={0}\u306E\u66F8\u8FBC\u307F\u30A8\u30E9\u30FC\u3067\u3059\u3002{1}
-javac.err.sourcepath.modulesourcepath.conflict=-sourcepath\u3068-modulesourcepath\u306E\u4E21\u65B9\u3092\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093
+javac.err.sourcepath.modulesourcepath.conflict=--source-path\u3068--module-source-path\u306E\u4E21\u65B9\u3092\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093
 javac.warn.source.target.conflict=\u30BD\u30FC\u30B9\u30FB\u30EA\u30EA\u30FC\u30B9{0}\u306B\u306F\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30EA\u30EA\u30FC\u30B9{1}\u304C\u5FC5\u8981\u3067\u3059
 javac.warn.target.default.source.conflict=\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30EA\u30EA\u30FC\u30B9{0}\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30BD\u30FC\u30B9\u30FB\u30EA\u30EA\u30FC\u30B9{1}\u3068\u7AF6\u5408\u3057\u3066\u3044\u307E\u3059
 javac.warn.profile.target.conflict=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB{0}\u306F\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30EA\u30EA\u30FC\u30B9{1}\u306B\u5BFE\u3057\u3066\u6709\u52B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093
 javac.err.file.not.found=\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}
 javac.err.file.not.directory=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u306F\u3042\u308A\u307E\u305B\u3093: {0}
 javac.err.file.not.file=\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u3042\u308A\u307E\u305B\u3093: {0}
+javac.err.cannot.access.runtime.env=\u5B9F\u884C\u6642\u74B0\u5883\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093
 
 ## messages
 
 javac.msg.usage.header=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <source files>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002
 
-javac.msg.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <source files>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-help\u3092\u4F7F\u7528\u3057\u307E\u3059
+javac.msg.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <source files>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001--help\u3092\u4F7F\u7528\u3057\u307E\u3059
 
 javac.msg.usage.nonstandard.footer=\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
 
@@ -219,8 +225,8 @@
 javac.version={0} {1}
 javac.fullVersion={0}\u30D5\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3"{1}"
 
-javac.err.release.bootclasspath.conflict=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306F-release\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
+javac.err.release.bootclasspath.conflict=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306F--release\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
 
 javac.err.unsupported.release.version=\u30EA\u30EA\u30FC\u30B9\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3{0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 
-javac.err.release.not.standard.file.manager=-release\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u6307\u5B9A\u3055\u308C\u305FJavaFileManager\u306FStandardJavaFileManager\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
+javac.err.release.not.standard.file.manager=--release\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u6307\u5B9A\u3055\u308C\u305FJavaFileManager\u306FStandardJavaFileManager\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -97,8 +97,8 @@
 javac.opt.Xlint.all=\u542F\u7528\u6240\u6709\u8B66\u544A
 javac.opt.Xlint.none=\u7981\u7528\u6240\u6709\u8B66\u544A
 #L10N: do not localize: -Xlint
-javac.opt.Xlint.subopts=-Xlint:key,...
-javac.opt.Xlint.suboptlist=\n        \u8981\u542F\u7528\u6216\u7981\u7528\u7684\u8B66\u544A, \u4F7F\u7528\u9017\u53F7\u5206\u9694\u3002\n        \u5728\u5173\u952E\u5B57\u524D\u9762\u52A0\u4E0A '-' \u53EF\u7981\u7528\u6307\u5B9A\u7684\u8B66\u544A\u3002\n        \u652F\u6301\u7684\u5173\u952E\u5B57\u5305\u62EC:
+javac.opt.arg.Xlint=<\u5BC6\u94A5>(,<\u5BC6\u94A5>)*
+javac.opt.Xlint.custom=\u8981\u542F\u7528\u6216\u7981\u7528\u7684\u8B66\u544A, \u4F7F\u7528\u9017\u53F7\u5206\u9694\u3002\n        \u5728\u5173\u952E\u5B57\u524D\u9762\u52A0\u4E0A '-' \u53EF\u7981\u7528\u6307\u5B9A\u7684\u8B66\u544A\u3002\n        \u652F\u6301\u7684\u5173\u952E\u5B57\u5305\u62EC:
 javac.opt.Xlint.desc.auxiliaryclass=\u6709\u5173\u8F85\u52A9\u7C7B\u5728\u6E90\u6587\u4EF6\u4E2D\u9690\u85CF, \u4F46\u5728\u5176\u4ED6\u6587\u4EF6\u4E2D\u4F7F\u7528\u7684\u8B66\u544A\u3002
 
 javac.opt.Xlint.desc.cast=\u6709\u5173\u4F7F\u7528\u4E86\u4E0D\u5FC5\u8981\u8F6C\u6362\u7684\u8B66\u544A\u3002
@@ -113,6 +113,8 @@
 
 javac.opt.Xlint.desc.empty=\u6709\u5173 if \u4E4B\u540E\u6CA1\u6709\u8BED\u53E5\u7684\u8B66\u544A\u3002
 
+javac.opt.Xlint.desc.exports=\u6709\u5173\u4E0E\u6A21\u5757\u5BFC\u51FA\u76F8\u5173\u7684\u95EE\u9898\u7684\u8B66\u544A\u3002
+
 javac.opt.Xlint.desc.fallthrough=\u6709\u5173\u4ECE switch \u8BED\u53E5\u7684\u4E00\u4E2A case \u5411\u4E0B\u987A\u5E8F\u6267\u884C\u5230\u4E0B\u4E00\u4E2A case \u7684\u8B66\u544A\u3002
 
 javac.opt.Xlint.desc.finally=\u6709\u5173 finally \u5B50\u53E5\u672A\u6B63\u5E38\u7EC8\u6B62\u7684\u8B66\u544A\u3002
@@ -129,7 +131,9 @@
 
 javac.opt.Xlint.desc.rawtypes=\u6709\u5173\u4F7F\u7528\u4E86\u539F\u59CB\u7C7B\u578B\u7684\u8B66\u544A\u3002
 
-javac.opt.Xlint.desc.serial=\u6709\u5173 Serializable \u5B50\u53E5\u672A\u63D0\u4F9B\u5E8F\u5217\u7248\u672C ID \u7684\u8B66\u544A\u3002
+javac.opt.Xlint.desc.removal=\u6709\u5173\u4F7F\u7528\u4E86\u6807\u8BB0\u4E3A\u5F85\u5220\u9664\u7684 API \u7684\u8B66\u544A\u3002
+
+javac.opt.Xlint.desc.serial=\u6709\u5173\u672A\u63D0\u4F9B\u5E8F\u5217\u7248\u672C ID \u7684\u53EF\u5E8F\u5217\u5316\u7C7B\u7684\u8B66\u544A\u3002\n                             \u6B64\u5916\u8FD8\u8B66\u544A\u6709\u5173\u53EF\u4E32\u884C\u5316\u5143\u7D20\u5BF9\u975E\u516C\u5171\u6210\u5458\u7684\u8BBF\u95EE\u3002
 
 javac.opt.Xlint.desc.static=\u6709\u5173\u4F7F\u7528\u5B9E\u4F8B\u6765\u8BBF\u95EE\u9759\u6001\u6210\u5458\u7684\u8B66\u544A\u3002
 
@@ -145,11 +149,11 @@
 
 # L10N: do not localize: accessibility html missing reference syntax
 # L10N: do not localize: public protected package private
-javac.opt.Xdoclint.custom=\n        \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n        \u5176\u4E2D <group> \u4E3A accessibility, html, missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n        <access> \u4E3A public, protected, package \u6216 private \u4E4B\u4E00\u3002
+javac.opt.Xdoclint.custom=\u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n        \u5176\u4E2D <group> \u4E3A accessibility, html, missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n        <access> \u4E3A public, protected, package \u6216 private \u4E4B\u4E00\u3002
 
-javac.opt.Xdoclint.package.args = ([-]<packages>)
+javac.opt.Xdoclint.package.args = [-]<\u7A0B\u5E8F\u5305>(,[-]<\u7A0B\u5E8F\u5305>)*
 
-javac.opt.Xdoclint.package.desc=\n        \u5728\u7279\u5B9A\u7684\u7A0B\u5E8F\u5305\u4E2D\u542F\u7528\u6216\u7981\u7528\u68C0\u67E5\u3002<packages> \u662F\u9017\u53F7\u5206\u9694\u7684\n        \u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u5217\u8868\u3002\u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u662F\u7A0B\u5E8F\u5305\u7684\u9650\u5B9A\u540D\u79F0\n        \u6216\u7A0B\u5E8F\u5305\u540D\u79F0\u524D\u7F00\u540E\u8DDF ''.*'', \u5B83\u6269\u5C55\u5230\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u7684\n        \u6240\u6709\u5B50\u7A0B\u5E8F\u5305\u3002\u5728\u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u524D\u9762\u52A0\u4E0A ''-'' \u53EF\u4EE5\u4E3A\n        \u6307\u5B9A\u7A0B\u5E8F\u5305\u7981\u7528\u68C0\u67E5\u3002
+javac.opt.Xdoclint.package.desc=\u5728\u7279\u5B9A\u7684\u7A0B\u5E8F\u5305\u4E2D\u542F\u7528\u6216\u7981\u7528\u68C0\u67E5\u3002\u6BCF\u4E2A <\u7A0B\u5E8F\u5305> \u662F\n\u7A0B\u5E8F\u5305\u7684\u9650\u5B9A\u540D\u79F0, \u6216\u7A0B\u5E8F\u5305\u540D\u79F0\u524D\u7F00\u540E\u8DDF '.*', \n\u5B83\u6269\u5C55\u5230\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u7684\u6240\u6709\u5B50\u7A0B\u5E8F\u5305\u3002\u5728\u6BCF\u4E2A <\u7A0B\u5E8F\u5305>\n\u524D\u9762\u52A0\u4E0A '-' \u53EF\u4EE5\u4E3A\u6307\u5B9A\u7A0B\u5E8F\u5305\u7981\u7528\u68C0\u67E5\u3002
 
 javac.opt.Xstdout=\u91CD\u5B9A\u5411\u6807\u51C6\u8F93\u51FA
 javac.opt.X=\u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981
@@ -161,18 +165,19 @@
 javac.opt.prefer=\u6307\u5B9A\u8BFB\u53D6\u6587\u4EF6, \u5F53\u540C\u65F6\u627E\u5230\u9690\u5F0F\u7F16\u8BD1\u7C7B\u7684\u6E90\u6587\u4EF6\u548C\u7C7B\u6587\u4EF6\u65F6
 javac.opt.AT=\u4ECE\u6587\u4EF6\u8BFB\u53D6\u9009\u9879\u548C\u6587\u4EF6\u540D
 javac.opt.diags=\u9009\u62E9\u8BCA\u65AD\u6A21\u5F0F
-javac.opt.addExports=\n        \u6307\u5B9A\u88AB\u89C6\u4E3A\u5DF2\u4ECE\u5176\u5B9A\u4E49\u6A21\u5757\u5BFC\u51FA\u5230\u5176\u4ED6\u6A21\u5757\u6216\u8005\u5BFC\u51FA\u5230\u6240\u6709\n        \u672A\u547D\u540D\u6A21\u5757 (\u5982\u679C <other-module> \u4E3A ALL-UNNAMED) \u7684\u7A0B\u5E8F\u5305\u3002
-javac.opt.arg.addExports=<module>/<package>=<other-module>(,<other-module>)*
-javac.opt.addReads=\n        \u6307\u5B9A\u88AB\u89C6\u4E3A\u7ED9\u5B9A\u6A21\u5757\u9700\u8981\u7684\u5176\u4ED6\u6A21\u5757\u3002\n        <other-module> \u53EF\u80FD\u9700\u8981\u4E3A ALL-UNNAMED, \u4EE5\u4FBF\u8981\u6C42\u672A\u547D\u540D\u6A21\u5757\u3002
-javac.opt.arg.addReads=<module>=<other-module>(,<other-module>)*
-javac.opt.patch=\n        \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\u8986\u76D6\n        \u6216\u589E\u5F3A\u6A21\u5757
+javac.opt.addExports=\u6307\u5B9A\u88AB\u89C6\u4E3A\u5DF2\u4ECE\u5176\u5B9A\u4E49\u6A21\u5757\u5BFC\u51FA\u5230\u5176\u4ED6\u6A21\u5757\u6216\u8005\u5BFC\u51FA\u5230\u6240\u6709\n        \u672A\u547D\u540D\u6A21\u5757 (\u5982\u679C <other-module> \u4E3A ALL-UNNAMED) \u7684\u7A0B\u5E8F\u5305\u3002
+javac.opt.arg.addExports=<\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*
+javac.opt.addReads=\u6307\u5B9A\u88AB\u89C6\u4E3A\u7ED9\u5B9A\u6A21\u5757\u9700\u8981\u7684\u5176\u4ED6\u6A21\u5757\u3002\n<other-module> \u53EF\u80FD\u9700\u8981\u4E3A ALL-UNNAMED, \u4EE5\u4FBF\u8981\u6C42\u672A\u547D\u540D\u6A21\u5757\u3002
+javac.opt.arg.addReads=<\u6A21\u5757>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*
+javac.opt.patch=\u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\u8986\u76D6\n        \u6216\u589E\u5F3A\u6A21\u5757
 javac.opt.arg.patch=<\u6A21\u5757>=<\u6587\u4EF6>(:<\u6587\u4EF6>)*
 javac.opt.module=\u6307\u5B9A\u6B63\u5728\u7F16\u8BD1\u7684\u7C7B\u6240\u5C5E\u7684\u6A21\u5757\u3002
-javac.opt.arg.module=<module-name>
-javac.opt.addmods=\n        \u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757; \u5982\u679C <module>\n        \u4E3A ALL-MODULE-PATH, \u5219\u4E3A\u6A21\u5757\u8DEF\u5F84\u4E2D\u7684\u6240\u6709\u6A21\u5757\u3002
-javac.opt.arg.addmods=<module>(,<module>)*
+javac.opt.arg.module=<\u6A21\u5757>
+javac.opt.addmods=\u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757; \u5982\u679C <module>\n        \u4E3A ALL-MODULE-PATH, \u5219\u4E3A\u6A21\u5757\u8DEF\u5F84\u4E2D\u7684\u6240\u6709\u6A21\u5757\u3002
+javac.opt.arg.addmods=<\u6A21\u5757>(,<\u6A21\u5757>)*
 javac.opt.limitmods=\u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF
-javac.opt.arg.limitmods=<module>(,<module>)*
+javac.opt.arg.limitmods=<\u6A21\u5757>(,<\u6A21\u5757>)*
+javac.opt.inherit_runtime_environment=\u4ECE\u8FD0\u884C\u65F6\u73AF\u5883\u7EE7\u627F\u6A21\u5757\u7CFB\u7EDF\u914D\u7F6E\u9009\u9879\u3002
 
 ## errors
 
@@ -190,19 +195,20 @@
 javac.err.req.arg={0}\u9700\u8981\u53C2\u6570
 javac.err.invalid.source=\u65E0\u6548\u7684\u6E90\u53D1\u884C\u7248: {0}
 javac.err.error.writing.file=\u5199\u5165{0}\u65F6\u51FA\u9519; {1}
-javac.err.sourcepath.modulesourcepath.conflict=\u65E0\u6CD5\u540C\u65F6\u6307\u5B9A -sourcepath \u4E0E -modulesourcepath
+javac.err.sourcepath.modulesourcepath.conflict=\u65E0\u6CD5\u540C\u65F6\u6307\u5B9A --source-path \u4E0E --module-source-path
 javac.warn.source.target.conflict=\u6E90\u53D1\u884C\u7248 {0} \u9700\u8981\u76EE\u6807\u53D1\u884C\u7248 {1}
 javac.warn.target.default.source.conflict=\u76EE\u6807\u53D1\u884C\u7248 {0} \u4E0E\u9ED8\u8BA4\u7684\u6E90\u53D1\u884C\u7248 {1} \u51B2\u7A81
 javac.warn.profile.target.conflict=\u914D\u7F6E\u6587\u4EF6{0}\u5BF9\u4E8E\u76EE\u6807\u53D1\u884C\u7248 {1} \u65E0\u6548
 javac.err.file.not.found=\u627E\u4E0D\u5230\u6587\u4EF6: {0}
 javac.err.file.not.directory=\u4E0D\u662F\u76EE\u5F55: {0}
 javac.err.file.not.file=\u4E0D\u662F\u6587\u4EF6: {0}
+javac.err.cannot.access.runtime.env=\u65E0\u6CD5\u8BBF\u95EE\u8FD0\u884C\u65F6\u73AF\u5883
 
 ## messages
 
 javac.msg.usage.header=\u7528\u6CD5: {0} <options> <source files>\n\u5176\u4E2D, \u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
 
-javac.msg.usage=\u7528\u6CD5: {0} <options> <source files>\n-help \u7528\u4E8E\u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
+javac.msg.usage=\u7528\u6CD5: {0} <\u9009\u9879> <\u6E90\u6587\u4EF6>\n\u4F7F\u7528 --help \u53EF\u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
 
 javac.msg.usage.nonstandard.footer=\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002
 
@@ -219,8 +225,8 @@
 javac.version={0} {1}
 javac.fullVersion={0}\u5B8C\u6574\u7248\u672C "{1}"
 
-javac.err.release.bootclasspath.conflict=\u9009\u9879{0}\u65E0\u6CD5\u4E0E -release \u4E00\u8D77\u4F7F\u7528
+javac.err.release.bootclasspath.conflict=\u9009\u9879 {0} \u4E0D\u80FD\u4E0E --release \u4E00\u8D77\u4F7F\u7528
 
 javac.err.unsupported.release.version=\u4E0D\u652F\u6301\u53D1\u884C\u7248\u672C {0}
 
-javac.err.release.not.standard.file.manager=\u6307\u5B9A\u4E86 -release \u9009\u9879, \u4F46\u63D0\u4F9B\u7684 JavaFileManager \u4E0D\u662F StandardJavaFileManager\u3002
+javac.err.release.not.standard.file.manager=\u6307\u5B9A\u4E86 --release \u9009\u9879, \u4F46\u63D0\u4F9B\u7684 JavaFileManager \u4E0D\u662F StandardJavaFileManager\u3002
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/resources/l10n_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/resources/l10n_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -47,23 +47,37 @@
 unknown.option={0}\u306F\u4E0D\u6B63\u306A\u5F15\u6570\u3067\u3059\n
 tracing.not.supported=\u8B66\u544A: \u30C8\u30EC\u30FC\u30B9\u306F\u73FE\u5728\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u304B\u308F\u308A\u306B\u3001Virtual Machine\u306E-verbose:jni\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 
-#
-# Usage message.
-#
-usage=\u4F7F\u7528\u65B9\u6CD5: javah [options] <classes>\n\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t-help           \u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n\t-classpath <path>   \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-cp <path>            \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-modulepath <path>    \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-system <path>        \u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30ED\u30FC\u30C9\u3059\u308BJDK\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-d<dir>         \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-o <file>         \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)\n\t-jni           JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n\t-version         \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n\t-verbose         \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n\t-force          \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\n\n<classes>\u306F\u5B8C\u5168\u4FEE\u98FE\u540D\u3067\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\n\u5148\u982D\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u306E\u5F8C\u306B'/'\u3092\u7D9A\u3051\u3066\u6307\u5B9A\u3057\u307E\u3059\u3002\u4F8B:\njava.lang.Object\njava.base/java.io.File\n
 main.usage=\u4F7F\u7528\u65B9\u6CD5: \n  javah [options] <classes>\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002
-main.opt.o=\  -o <file>                \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)
-main.opt.d=\  -d <dir>                 \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
-main.opt.v=\  -v  -verbose             \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046
-main.opt.h=\  -h  --help  -?           \u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B
-main.opt.version=\  -version                 \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B
-main.opt.jni=\  -jni                     JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)
-main.opt.force=\  -force                   \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080
-main.opt.classpath=\  -classpath <path>        \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
-main.opt.cp=\  -cp <path>               \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
-main.opt.bootclasspath=\  -bootclasspath <path>    \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
-main.usage.foot=<classes>\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002
+
+main.opt.o=\  -o <file>                    \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)
+
+main.opt.d=\  -d <dir>                     \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
+
+main.opt.v=\  -v  -verbose                 \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046
+
+main.opt.h=\  -h  --help  -?               \u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B
+
+main.opt.version=\  -version                     \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B
+
+main.opt.jni=\  -jni                         JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)
+
+main.opt.force=\  -force                       \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080
 
+main.opt.module_path=\  --module-path <path>         \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
+
+main.opt.upgrade_module_path=\  --upgrade_module-path <path> \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
+
+main.opt.classpath=\  -classpath <path>            \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
+
+main.opt.class_path=\  --class-path <path>          \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
+
+main.opt.cp=\  -cp <path>                   \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
+
+main.opt.bootclasspath=\  -bootclasspath <path>        \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9
+
+main.opt.system=\  --system <jdk>               \u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+
+main.usage.foot=\nGNU\u30B9\u30BF\u30A4\u30EB\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u306F\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u540D\u524D\u3068\u305D\u306E\u5024\u3092\u533A\u5207\u308B\u305F\u3081\u306B\u7A7A\u767D\u3067\u306F\u306A\u304F'='\u3092\n\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n\n\u5404\u30AF\u30E9\u30B9\u306F\u3001\u305D\u306E\u5B8C\u5168\u4FEE\u98FE\u540D\u3067\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u306E\n\u63A5\u982D\u8F9E\u306B\u7D9A\u3051\u3066'/'\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u4F8B:\n    java.lang.Object\n    java.base/java.io.File\n
 #
 # Version string.
 #
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -47,23 +47,37 @@
 unknown.option={0}\u662F\u975E\u6CD5\u53C2\u6570\n
 tracing.not.supported=\u8B66\u544A: \u4E0D\u518D\u652F\u6301\u8DDF\u8E2A\u3002\u8BF7\u4F7F\u7528\u865A\u62DF\u673A\u7684 -verbose:jni \u9009\u9879\u3002
 
-#
-# Usage message.
-#
-usage=\u7528\u6CD5: javah [options] <classes>\n\n\u5176\u4E2D, [options] \u5305\u62EC:\n\n\t-help                 \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\u5E76\u9000\u51FA\n\t-classpath <path>     \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-cp <path>            \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-modulepath <path>    \u4ECE\u4E2D\u52A0\u8F7D\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u8DEF\u5F84\n\t-system <path>        \u4ECE\u4E2D\u52A0\u8F7D\u7CFB\u7EDF\u6A21\u5757\u7684 JDK \u76EE\u5F55\n\t-d <dir>              \u8F93\u51FA\u76EE\u5F55\n\t-o <file>             \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)\n\t-jni                  \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)\n\t-version              \u8F93\u51FA\u7248\u672C\u4FE1\u606F\n\t-verbose              \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n\t-force                \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6\n\n<classes> \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684, \u53EF\u4EE5\u9009\u62E9\u6027\u5730\n\u4F7F\u7528\u6A21\u5757\u540D\u540E\u8DDF '/' \u4F5C\u4E3A\u524D\u7F00\u3002\u793A\u4F8B:\njava.lang.Object\njava.base/java.io.File\n
 main.usage=\u7528\u6CD5: \n  javah [options] <classes>\n\u5176\u4E2D, [options] \u5305\u62EC:
-main.opt.o=\  -o <file>                \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)
-main.opt.d=\  -d <dir>                 \u8F93\u51FA\u76EE\u5F55
-main.opt.v=\  -v  -verbose             \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA
-main.opt.h=\  -h  --help  -?           \u8F93\u51FA\u6B64\u6D88\u606F
-main.opt.version=\  -version                 \u8F93\u51FA\u7248\u672C\u4FE1\u606F
-main.opt.jni=\  -jni                     \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)
-main.opt.force=\  -force                   \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6
-main.opt.classpath=\  -classpath <path>        \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84
-main.opt.cp=\  -cp <path>               \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84
-main.opt.bootclasspath=\  -bootclasspath <path>    \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84
-main.usage.foot=<classes> \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684\n(\u4F8B\u5982, java.lang.Object)\u3002
+
+main.opt.o=\  -o <file>                    \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)
+
+main.opt.d=\  -d <dir>                     \u8F93\u51FA\u76EE\u5F55
+
+main.opt.v=\  -v  -verbose                 \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA
+
+main.opt.h=\  -h  --help  -?               \u8F93\u51FA\u6B64\u6D88\u606F
+
+main.opt.version=\  -version                     \u8F93\u51FA\u7248\u672C\u4FE1\u606F
+
+main.opt.jni=\  -jni                         \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)
+
+main.opt.force=\  -force                       \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6
 
+main.opt.module_path=\  --module-path <\u8DEF\u5F84>         \u4ECE\u4E2D\u52A0\u8F7D\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u8DEF\u5F84
+
+main.opt.upgrade_module_path=\  --upgrade_module-path <\u8DEF\u5F84> \u4ECE\u4E2D\u52A0\u8F7D\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u8DEF\u5F84
+
+main.opt.classpath=\  -classpath <path>            \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84
+
+main.opt.class_path=\  --class-path <\u8DEF\u5F84>          \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84
+
+main.opt.cp=\  -cp <path>                   \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84
+
+main.opt.bootclasspath=\  -bootclasspath <path>        \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84
+
+main.opt.system=\  --system <jdk>               \u6307\u5B9A\u67E5\u627E\u7CFB\u7EDF\u6A21\u5757\u7684\u4F4D\u7F6E
+
+main.usage.foot=\nGNU \u6837\u5F0F\u7684\u9009\u9879\u53EF\u4F7F\u7528 '=' (\u800C\u975E\u7A7A\u767D) \u6765\u5206\u9694\u9009\u9879\u540D\u79F0\n\u53CA\u5176\u503C\u3002\n\n\u6BCF\u4E2A\u7C7B\u5FC5\u987B\u7531\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A, \n\u53EF\u4EE5\u9009\u62E9\u6027\u5730\u4F7F\u7528\u6A21\u5757\u540D\u540E\u8DDF '/' \u4F5C\u4E3A\u524D\u7F00\u3002\u793A\u4F8B:\n    java.lang.Object\n    java.base/java.io.File\n
 #
 # Version string.
 #
--- a/langtools/src/jdk.compiler/share/classes/module-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -81,5 +81,8 @@
 
     provides javax.tools.JavaCompiler
         with com.sun.tools.javac.api.JavacTool;
+
+    provides javax.tools.Tool
+        with com.sun.tools.javac.api.JavacTool;
 }
 
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -28,9 +28,12 @@
 main.warnings=\u8B66\u544A{0}\u500B
 main.warning=\u8B66\u544A{0}\u500B
 
-main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n  -overview <file>          HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n  -public                   public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n  -protected                protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n  -package                  package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n  -private                  \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n  -help                     \u30B3\u30DE\u30F3\u30C9\u884C\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n  -doclet <class>           \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n  -docletpath <path>        doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u63A2\u3059\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -sourcepath <pathlist>    \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -classpath <pathlist>     \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -cp <pathlist>                   \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\r\n  -exclude <pkglist>        \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n  -subpackages <subpkglist> \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n  -breakiterator            BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n  -bootclasspath <pathlist> \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30ED\u30FC\u30C0\u30FC\u306B\u3088\u308A\u30ED\u30FC\u30C9\u3055\u308C\u305F\n                                   \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  -source <release>         \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n  -extdirs <dirlist>        \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  -verbose                  Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n  -locale <name>            en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n  -encoding <name>          \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n  -quiet                    \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n  -J<flag>                  <flag>\u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n  -X                        \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u7D42\u4E86\u3059\u308B\n
+main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n  -overview <file>                 HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n  -public                          public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n  -protected                       protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n  -package                         package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n  -private                         \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n  -help                            \u30B3\u30DE\u30F3\u30C9\u884C\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n  -doclet <class>                  \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n  -docletpath <path>               doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  --module-source-path <path>      \u8907\u6570\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u5165\u529B\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  --upgrade-module-path <path>     \u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  --module-path <path>\u3001-p <path>  \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  --add-modules <module>(,<module>)*\n                                   \u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F\n                                   <module>\u304CALL-MODULE-PATH\u3067\u3042\u308B\u5834\u5408\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3002\n  --limit-modules <module>(,<module>)*\n                                   \u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3059\u308B\n  --source-path <path>             \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -sourcepath <path>               \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  --class-path <path>              \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -classpath <path>                \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -cp <path>                       \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -exclude <pkglist>               \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n  -subpackages <subpkglist>        \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n  -breakiterator                   BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n  -bootclasspath <path>            \u975E\u30E2\u30B8\u30E5\u30E9\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u4F7F\u7528\u3055\u308C\u308B\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\n                                   \
+\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  --system <jdk>                   \u30E2\u30B8\u30E5\u30E9\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u4F7F\u7528\u3055\u308C\u308B\u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\n                                   \u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\u3002\n  -source <release>                \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n  --release <release>              \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n  -extdirs <dirlist>               \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  -verbose                         Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n  -locale <name>                   en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n  -encoding <name>                 \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n  -quiet                           \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n  -J<flag>                         <flag>\u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n  -X                               \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u7D42\u4E86\u3059\u308B\n
 
-main.Xusage=\  -Xmaxerrs <number>        \u51FA\u529B\u3059\u308B\u30A8\u30E9\u30FC\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n  -Xmaxwarns <number>       \u51FA\u529B\u3059\u308B\u8B66\u544A\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n
+main.usage.foot=\nGNU\u30B9\u30BF\u30A4\u30EB\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u306F\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u540D\u524D\u3068\u305D\u306E\u5024\u3092\u533A\u5207\u308B\u305F\u3081\u306B\u7A7A\u767D\u3067\u306F\u306A\u304F'='\u3092\n\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n
+
+main.Xusage=\  -Xmaxerrs <number>               \u51FA\u529B\u3059\u308B\u6700\u5927\u30A8\u30E9\u30FC\u6570\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n  -Xmaxwarns <number>              \u51FA\u529B\u3059\u308B\u6700\u5927\u8B66\u544A\u6570\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n  --add-exports <module>/<package>=<other-module>(,<other-module>)*\n                                   \u305D\u306E\u5B9A\u7FA9\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\u3001\u8FFD\u52A0\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F<other-module>\u304C \n                                   ALL-UNNAMED\u3067\u3042\u308B\u5834\u5408\u306F\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B \n                                   \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u6E08\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n  --add-reads <module>=<other-module>(,<other-module>)*\n                                   \u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u5FC5\u9808\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n                                   \u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u5834\u5408\u3001<other-module>\u306FALL-UNNAMED\n                                   \u306B\u3057\u307E\u3059\u3002\n  -Xmodule:<module-name>           \u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u304C\u5C5E\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n  --patch-module <module>=<file>(:<file>)*\n                                   JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n                                   \u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3057\u307E\u3059\n
 
 main.Xusage.foot=\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
 
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -28,9 +28,12 @@
 main.warnings={0} \u4E2A\u8B66\u544A
 main.warning={0} \u4E2A\u8B66\u544A
 
-main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n  -overview <file>                 \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n  -public                          \u4EC5\u663E\u793A public \u7C7B\u548C\u6210\u5458\n  -protected                       \u663E\u793A protected/public \u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n  -package                         \u663E\u793A package/protected/public \u7C7B\u548C\u6210\u5458\n  -private                         \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n  -help                            \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n  -doclet <class>                  \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n  -docletpath <path>               \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -sourcepath <pathlist>           \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -classpath <pathlist>            \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -cp <pathlist>                   \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -exclude <pkglist>               \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n  -subpackages <subpkglist>        \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n  -breakiterator                   \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n  -bootclasspath <pathlist>        \u8986\u76D6\u7531\u5F15\u5BFC\u7C7B\u52A0\u8F7D\u5668\u6240\u52A0\u8F7D\u7684\n                                   \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -source <release>                \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n  -extdirs <dirlist>               \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n  -verbose                         \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u4FE1\u606F\n  -locale <name>                   \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n  -encoding <name>                 \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n  -quiet                           \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n  -J<flag>                         \u76F4\u63A5\u5C06 <flag> \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n  -X                               \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\n
+main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n  -overview <\u6587\u4EF6>                 \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n  -public                          \u4EC5\u663E\u793A\u516C\u5171\u7C7B\u548C\u6210\u5458\n  -protected                       \u663E\u793A\u53D7\u4FDD\u62A4/\u516C\u5171\u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n  -package                         \u663E\u793A\u7A0B\u5E8F\u5305/\u53D7\u4FDD\u62A4/\u516C\u5171\u7C7B\u548C\u6210\u5458\n  -private                         \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n  -help                            \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n  -doclet <\u7C7B>                     \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n  -docletpath <\u8DEF\u5F84>               \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  --module-source-path <\u8DEF\u5F84>      \u6307\u5B9A\u67E5\u627E\u591A\u4E2A\u6A21\u5757\u7684\u8F93\u5165\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n  --upgrade-module-path <\u8DEF\u5F84>     \u8986\u76D6\u53EF\u5347\u7EA7\u6A21\u5757\u4F4D\u7F6E\n  --module-path <\u8DEF\u5F84>, -p <\u8DEF\u5F84>  \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E\n  --add-modules <\u6A21\u5757>(,<\u6A21\u5757>)*\n                                   \u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757,\n                                   \u5982\u679C <\u6A21\u5757>\u4E3A ALL-MODULE-PATH, \u5219\u4E3A\u6A21\u5757\u8DEF\u5F84\u4E2D\u7684\u6240\u6709\u6A21\u5757\u3002\n  --limit-modules <\u6A21\u5757>(,<\u6A21\u5757>)*\n                                   \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF\n  --source-path <\u8DEF\u5F84>             \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -sourcepath <\u8DEF\u5F84>               \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n  --class-path <\u8DEF\u5F84>              \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -classpath <\u8DEF\u5F84>                \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -cp <\u8DEF\u5F84>                       \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -exclude <\u7A0B\u5E8F\u5305\u5217\u8868>            \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n  -subpackages <\u7A0B\u5E8F\u5305\u5217\u8868>        \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n  -breakiterator                   \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n  -bootclasspath <\u8DEF\u5F84>            \u8986\u76D6\u7528\u4E8E\u975E\u6A21\u5757\u5316\u53D1\u884C\u7248\u7684\n                                   \u5E73\u53F0\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  --system <jdk>                   \u8986\u76D6\u7528\u4E8E\u6A21\u5757\u5316\u53D1\u884C\u7248\u7684\n                                   \u7CFB\u7EDF\u6A21\u5757\u7684\u4F4D\u7F6E\u3002\n  -source <\u53D1\u884C\u7248>                 \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n  --release <\u53D1\u884C\u7248>               \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n  -extdirs <\u76EE\u5F55\u5217\u8868>              \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n  -verbose                         \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u6D88\u606F\n  -locale <\u540D\u79F0>                   \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n  -encoding <\u540D\u79F0>                 \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n  -quiet                           \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n  -J<\u6807\u8BB0>                         \u76F4\u63A5\u5C06 <\u6807\u8BB0> \
+\u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n  -X                               \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\u5E76\u9000\u51FA\n
 
-main.Xusage=\  -Xmaxerrs <number>               \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u9519\u8BEF\u6570\n  -Xmaxwarns <number>              \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u8B66\u544A\u6570\n
+main.usage.foot=\nGNU \u6837\u5F0F\u7684\u9009\u9879\u53EF\u4F7F\u7528 '=' (\u800C\u975E\u7A7A\u767D) \u6765\u5206\u9694\u9009\u9879\u540D\u79F0\n\u53CA\u5176\u503C\u3002\n
+
+main.Xusage=\  -Xmaxerrs <\u6570\u5B57>                 \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u9519\u8BEF\u7684\u6700\u5927\u6570\u76EE\n  -Xmaxwarns <\u6570\u5B57>                \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u8B66\u544A\u7684\u6700\u5927\u6570\u76EE\n  --add-exports <\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*\n                                   \u6307\u5B9A\u5C06\u7A0B\u5E8F\u5305\u89C6\u4E3A\u4ECE\u5176\u5B9A\u4E49\u6A21\u5757\u5BFC\u51FA\u5230\u5176\u4ED6\u6A21\u5757, \n                                   \u5982\u679C <\u5176\u4ED6\u6A21\u5757> \u4E3A ALL-UNNAMED, \u5219\u89C6\u4E3A\n                                   \u5BFC\u51FA\u5230\u6240\u6709\u672A\u547D\u540D\u6A21\u5757\u3002\n  --add-reads <\u6A21\u5757>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*\n                                   \u6307\u5B9A\u88AB\u89C6\u4E3A\u7ED9\u5B9A\u6A21\u5757\u9700\u8981\u7684\u5176\u4ED6\u6A21\u5757\u3002\n                                   <\u5176\u4ED6\u6A21\u5757> \u53EF\u4EE5\u4E3A ALL-UNNAMED \u4EE5\u4FBF\u8981\u6C42\n                                   \u672A\u547D\u540D\u6A21\u5757\u3002\n  -Xmodule:<\u6A21\u5757\u540D\u79F0>              \u6307\u5B9A\u6B63\u5728\u7F16\u8BD1\u7684\u7C7B\u6240\u5C5E\u7684\u6A21\u5757\u3002\n  --patch-module <\u6A21\u5757>=<\u6587\u4EF6>(:<\u6587\u4EF6>)*\n                                   \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\n                                   \u8986\u76D6\u6216\u589E\u5F3A\u6A21\u5757\n
 
 main.Xusage.foot=\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002
 
@@ -59,8 +62,8 @@
 main.doclet_method_not_accessible=\u5728 doclet \u7C7B{0}\u4E2D, \u65E0\u6CD5\u8BBF\u95EE\u65B9\u6CD5{1}
 main.internal_error_exception_thrown=\u5185\u90E8\u9519\u8BEF: \u5728 doclet \u7C7B{0}\u4E2D, \u65B9\u6CD5{1}\u5DF2\u629B\u51FA\u5F02\u5E38\u9519\u8BEF{2}
 main.exception_thrown=\u5728 doclet \u7C7B{0}\u4E2D, \u65B9\u6CD5{1}\u5DF2\u629B\u51FA\u5F02\u5E38\u9519\u8BEF{2}
-main.illegal_locale_name=\u8BED\u8A00\u73AF\u5883\u4E0D\u53EF\u7528: {0}
-main.malformed_locale_name=\u683C\u5F0F\u9519\u8BEF\u7684\u8BED\u8A00\u73AF\u5883\u540D\u79F0: {0}
+main.illegal_locale_name=\u533A\u57DF\u8BBE\u7F6E\u4E0D\u53EF\u7528: {0}
+main.malformed_locale_name=\u683C\u5F0F\u9519\u8BEF\u7684\u533A\u57DF\u8BBE\u7F6E\u540D\u79F0: {0}
 main.file_not_found=\u627E\u4E0D\u5230\u6587\u4EF6: "{0}"
 main.file_ignored=\u5DF2\u5FFD\u7565\u6587\u4EF6: "{0}" (\u5C1A\u4E0D\u652F\u6301)
 main.illegal_class_name=\u975E\u6CD5\u7C7B\u540D: "{0}"
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java	Tue Dec 13 02:04:23 2016 +0100
@@ -62,6 +62,11 @@
  * or deletion without notice.</b></p>
  */
 public class JavadocTool implements DocumentationTool {
+    // @Override // can't add @Override until bootstrap JDK provides Tool.name()
+    public String name() {
+        return "javadoc";
+    }
+
     @Override
     public DocumentationTask getTask(
             Writer out,
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Tue Dec 13 02:04:23 2016 +0100
@@ -117,12 +117,12 @@
         HtmlTree rightContainerDiv = new HtmlTree(HtmlTag.DIV);
         leftContainerDiv.addStyle(HtmlStyle.leftContainer);
         rightContainerDiv.addStyle(HtmlStyle.rightContainer);
-        if (noOfPackages <= 1) {
-            addAllClassesFrameTag(leftContainerDiv);
+        if (configuration.showModules && configuration.modules.size() > 1) {
+            addAllModulesFrameTag(leftContainerDiv);
         } else if (noOfPackages > 1) {
             addAllPackagesFrameTag(leftContainerDiv);
-            addAllClassesFrameTag(leftContainerDiv);
         }
+        addAllClassesFrameTag(leftContainerDiv);
         addClassFrameTag(rightContainerDiv);
         HtmlTree mainContainer = HtmlTree.DIV(HtmlStyle.mainContainer, leftContainerDiv);
         mainContainer.addContent(rightContainerDiv);
@@ -130,6 +130,18 @@
     }
 
     /**
+     * Add the IFRAME tag for the frame that lists all modules.
+     *
+     * @param contentTree to which the information will be added
+     */
+    private void addAllModulesFrameTag(Content contentTree) {
+        HtmlTree frame = HtmlTree.IFRAME(DocPaths.MODULE_OVERVIEW_FRAME.getPath(),
+                "packageListFrame", configuration.getText("doclet.All_Modules"));
+        HtmlTree leftTop = HtmlTree.DIV(HtmlStyle.leftTop, frame);
+        contentTree.addContent(leftTop);
+    }
+
+    /**
      * Add the IFRAME tag for the frame that lists all packages.
      *
      * @param contentTree the content tree to which the information will be added
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -31,6 +31,11 @@
 doclet.Href_Class_Or_Interface_Title={0}\u5185\u306E\u30AF\u30E9\u30B9\u307E\u305F\u306F\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
 doclet.Summary=\u6982\u8981:
 doclet.Detail=\u8A73\u7D30:
+doclet.Module_Sub_Nav=\u30E2\u30B8\u30E5\u30FC\u30EB:
+doclet.navModuleDescription=\u8AAC\u660E
+doclet.navModules=\u30E2\u30B8\u30E5\u30FC\u30EB
+doclet.navPackages=\u30D1\u30C3\u30B1\u30FC\u30B8
+doclet.navServices=\u30B5\u30FC\u30D3\u30B9
 doclet.navNested=\u30CD\u30B9\u30C8
 doclet.navAnnotationTypeOptionalMember=\u30AA\u30D7\u30B7\u30E7\u30F3
 doclet.navAnnotationTypeRequiredMember=\u5FC5\u9808
@@ -57,6 +62,7 @@
 doclet.Static_method_in={0}\u306Estatic\u30E1\u30BD\u30C3\u30C9
 doclet.Search_tag_in={0}\u306E\u691C\u7D22\u30BF\u30B0
 doclet.Method_in={0}\u306E\u30E1\u30BD\u30C3\u30C9
+doclet.module=\u30E2\u30B8\u30E5\u30FC\u30EB
 doclet.package=\u30D1\u30C3\u30B1\u30FC\u30B8
 doclet.MalformedURL=\u4E0D\u6B63\u306AURL: {0}
 doclet.File_error=\u30D5\u30A1\u30A4\u30EB\u8AAD\u8FBC\u307F\u30A8\u30E9\u30FC: {0}
@@ -91,7 +97,6 @@
 doclet.deprecated_annotation_type_members=\u63A8\u5968\u3055\u308C\u3066\u3044\u306A\u3044\u6CE8\u91C8\u578B\u306E\u8981\u7D20
 doclet.Generated_Docs_Untitled=\u751F\u6210\u3055\u308C\u305F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8(\u30BF\u30A4\u30C8\u30EB\u306A\u3057)
 doclet.Other_Packages=\u305D\u306E\u4ED6\u306E\u30D1\u30C3\u30B1\u30FC\u30B8
-doclet.Package_Description=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306E\u8AAC\u660E
 doclet.Description=\u8AAC\u660E
 doclet.Specified_By=\u5B9A\u7FA9:
 doclet.in_interface=\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u5185
@@ -99,7 +104,7 @@
 doclet.Subinterfaces=\u65E2\u77E5\u306E\u30B5\u30D6\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306E\u30EA\u30B9\u30C8:
 doclet.Implementing_Classes=\u65E2\u77E5\u306E\u5B9F\u88C5\u30AF\u30E9\u30B9\u306E\u30EA\u30B9\u30C8:
 doclet.Functional_Interface=\u6A5F\u80FD\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
-doclet.Functional_Interface_Message=\u3053\u308C\u306F\u6A5F\u80FD\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306A\u306E\u3067\u3001\u30E9\u30E0\u30C0\u5F0F\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u5272\u5F53\u3066\u30BF\u30FC\u30B2\u30C3\u30C8\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
+doclet.Functional_Interface_Message=\u3053\u308C\u306F\u6A5F\u80FD\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306A\u306E\u3067\u3001\u30E9\u30E0\u30C0\u5F0F\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u5272\u5F53\u3066\u30BF\u30FC\u30B2\u30C3\u30C8\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002 
 doclet.also=\u540C\u69D8\u306B
 doclet.Frames=\u30D5\u30EC\u30FC\u30E0
 doclet.No_Frames=\u30D5\u30EC\u30FC\u30E0\u306A\u3057
@@ -183,159 +188,121 @@
 doclet.Error_in_packagelist=-group\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u30A8\u30E9\u30FC: {0} {1}
 doclet.Groupname_already_used=-group\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u304A\u3044\u3066\u3001\u3059\u3067\u306B\u30B0\u30EB\u30FC\u30D7\u540D\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059: {0}
 doclet.Same_package_name_used=\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u5F62\u5F0F\u304C2\u56DE\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059: {0}
-doclet.exception_encountered={1}\u306E\u51E6\u7406\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\n{0}
 
 # option specifiers
-doclet.usage.d.name=d
 doclet.usage.d.parameters=<directory>
 doclet.usage.d.description=\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
 
-doclet.usage.use.name=use
 doclet.usage.use.description=\u30AF\u30E9\u30B9\u3068\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4F7F\u7528\u30DA\u30FC\u30B8\u3092\u4F5C\u6210\u3057\u307E\u3059
 
-doclet.usage.version.name=version
 doclet.usage.version.description=@version\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.author.name=author
 doclet.usage.author.description=@author\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.docfilessubdirs.name=docfilessubdirs
 doclet.usage.docfilessubdirs.description=doc-file\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u518D\u5E30\u7684\u306B\u30B3\u30D4\u30FC\u3057\u307E\u3059
 
-doclet.usage.splitindex.name=splitindex
 doclet.usage.splitindex.description=1\u5B57\u3054\u3068\u306B1\u30D5\u30A1\u30A4\u30EB\u306B\u7D22\u5F15\u3092\u5206\u5272\u3057\u307E\u3059
 
-doclet.usage.windowtitle.name=windowtitle
-doclet.usage.windotitle.parameters=<text>
+doclet.usage.overview.parameters=<file>
+doclet.usage.overview.description=HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u307F\u307E\u3059
+
+doclet.usage.windowtitle.parameters=<text>
 doclet.usage.windowtitle.description=\ \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7528\u306E\u30D6\u30E9\u30A6\u30B6\u30FB\u30A6\u30A3\u30F3\u30C9\u30A6\u30FB\u30BF\u30A4\u30C8\u30EB
 
-doclet.usage.doctitle.name=doctitle
 doclet.usage.doctitle.parameters=<html-code>
 doclet.usage.doctitle.description=\u6982\u8981\u30DA\u30FC\u30B8\u306B\u30BF\u30A4\u30C8\u30EB\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.header.name=\u30D8\u30C3\u30C0\u30FC
 doclet.usage.header.parameters=<html-code>
 doclet.usage.header.description=\u5404\u30DA\u30FC\u30B8\u306B\u30D8\u30C3\u30C0\u30FC\u30FB\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.html4.name=html4
 doclet.usage.html4.description=HTML 4.01\u51FA\u529B\u3092\u751F\u6210\u3057\u307E\u3059
 
-doclet.usage.html5.name=html5
 doclet.usage.html5.description=HTML 5\u51FA\u529B\u3092\u751F\u6210\u3057\u307E\u3059
 
-doclet.usage.footer.name=\u30D5\u30C3\u30BF\u30FC
 doclet.usage.footer.parameters=<html-code>
 doclet.usage.footer.description=\u5404\u30DA\u30FC\u30B8\u306B\u30D5\u30C3\u30BF\u30FC\u30FB\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.top.name=top
 doclet.usage.top.parameters=<html-code>
 doclet.usage.top.description=\u5404\u30DA\u30FC\u30B8\u306B\u4E0A\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.bottom.name=bottom
 doclet.usage.bottom.parameters=<html-code>
 doclet.usage.bottom.description=\u5404\u30DA\u30FC\u30B8\u306B\u4E0B\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.link.name=link
 doclet.usage.link.parameters=<url>
 doclet.usage.link.description=<url>\u306Bjavadoc\u51FA\u529B\u3078\u306E\u30EA\u30F3\u30AF\u3092\u4F5C\u6210\u3057\u307E\u3059
 
-doclet.usage.linkoffline.name=linkoffline
 doclet.usage.linkoffline.parameters=<url1> <url2>
 doclet.usage.linkoffline.description=<url2>\u306B\u3042\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u4F7F\u7528\u3057\u3066<url1>\u306Edocs\u306B\u30EA\u30F3\u30AF\u3057\u307E\u3059
 
-doclet.usage.excludedocfilessubdir.name=excludedocfilessubdir
 doclet.usage.excludedocfilessubdir.parameters=<name>:..
-doclet.usage.excludedocfilessubdir.description=\n                                  \u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u306Edoc-files\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u3059\u3079\u3066\u9664\u5916\u3057\u307E\u3059
+doclet.usage.excludedocfilessubdir.description=\u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u306Edoc-files\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u3059\u3079\u3066\u9664\u5916\u3057\u307E\u3059
 
-doclet.usage.group.name=group
 doclet.usage.group.parameters=<name> <p1>:<p2>..
 doclet.usage.group.description=\u6307\u5B9A\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6982\u8981\u30DA\u30FC\u30B8\u306B\u304A\u3044\u3066\u30B0\u30EB\u30FC\u30D7\u5316\u3057\u307E\u3059
 
-doclet.usage.nocomment.name=nocomment
 doclet.usage.nocomment.description=\u8A18\u8FF0\u304A\u3088\u3073\u30BF\u30B0\u3092\u6291\u5236\u3057\u3066\u5BA3\u8A00\u306E\u307F\u3092\u751F\u6210\u3057\u307E\u3059
 
-doclet.usage.nodeprecated.name=nodeprecated
 doclet.usage.nodeprecated.description=@deprecated\u60C5\u5831\u3092\u9664\u5916\u3057\u307E\u3059
 
-doclet.usage.noqualifier.name=noqualifier
 doclet.usage.noqualifier.parameters=<name1>:<name2>:..
 doclet.usage.noqualifier.description=\u51FA\u529B\u304B\u3089\u4FEE\u98FE\u5B50\u306E\u30EA\u30B9\u30C8\u3092\u9664\u5916\u3057\u307E\u3059
 
-doclet.usage.nosince.name=nosince
 doclet.usage.nosince.description=@since\u60C5\u5831\u3092\u9664\u5916\u3057\u307E\u3059
 
-doclet.usage.notimestamp.name=notimestamp
 doclet.usage.notimestamp.description=\u975E\u8868\u793A\u306E\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u3092\u9664\u5916\u3057\u307E\u3059
 
-doclet.usage.nodeprecatedlist.name=nodeprecatedlist
 doclet.usage.nodeprecatedlist.description=\u975E\u63A8\u5968\u306E\u30EA\u30B9\u30C8\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.notree.name=notree
 doclet.usage.notree.description=\u30AF\u30E9\u30B9\u968E\u5C64\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.noindex.name=noindex
 doclet.usage.noindex.description=\u7D22\u5F15\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.nohelp.name=nohelp
 doclet.usage.nohelp.description=\u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.nonavbar.name=nonavbar
 doclet.usage.nonavbar.description=\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.nooverview.name=nooverview
 doclet.usage.nooverview.description=\u6982\u8981\u30DA\u30FC\u30B8\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.serialwarn.name=serialwarn
 doclet.usage.serialwarn.description=@serial\u30BF\u30B0\u306B\u95A2\u3059\u308B\u8B66\u544A\u3092\u751F\u6210\u3057\u307E\u305B\u3093
 
-doclet.usage.tag.name=tag
 doclet.usage.tag.parameters=<name>:<locations>:<header>
-doclet.usage.tag.description=\n                                  \u5358\u4E00\u306E\u5F15\u6570\u3092\u6301\u3064\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u3092\u6307\u5B9A\u3057\u307E\u3059
+doclet.usage.tag.description=\u5358\u4E00\u306E\u5F15\u6570\u3092\u6301\u3064\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-doclet.usage.taglet.name=taglet
 doclet.usage.taglet.description=\u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u5B8C\u5168\u4FEE\u98FE\u540D\u3092\u767B\u9332\u3057\u307E\u3059
 
-doclet.usage.tagletpath.name=tagletpath
 doclet.usage.tagletpath.description=\u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u30D1\u30B9
 
-doclet.usage.charset.name=charset
 doclet.usage.charset.parameters=<charset>
 doclet.usage.charset.description=\u751F\u6210\u3055\u308C\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30AF\u30ED\u30B9\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3067\u306E\u6587\u5B57\u30BB\u30C3\u30C8
 
-doclet.usage.helpfile.name=helpfile
 doclet.usage.helpfile.parameters=<file>
 doclet.usage.helpfile.description=\u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u306E\u30EA\u30F3\u30AF\u5148\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.linksource.name=linksource
 doclet.usage.linksource.description=HTML\u5F62\u5F0F\u3067\u30BD\u30FC\u30B9\u3092\u751F\u6210\u3057\u307E\u3059
 
-doclet.usage.sourcetab.name=sourcetab
 doclet.usage.sourcetab.parameters=<tab length>
 doclet.usage.sourcetab.description=\u30BD\u30FC\u30B9\u5185\u306E\u30BF\u30D6\u306E\u7A7A\u767D\u6587\u5B57\u306E\u6570\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-doclet.usage.keywords.name=keywords
 doclet.usage.keywords.description=HTML\u306Emeta\u30BF\u30B0\u306B\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u3001\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u60C5\u5831\u3092\u542B\u3081\u307E\u3059
 
-doclet.usage.stylesheetfile.name=stylesheetfile
 doclet.usage.stylesheetfile.parameters=<path>
 doclet.usage.stylesheetfile.description=\u751F\u6210\u3055\u308C\u305F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u5909\u66F4\u7528\u30D5\u30A1\u30A4\u30EB
 
-doclet.usage.docencoding.name=docencoding
 doclet.usage.docencoding.parameters=<name>
 doclet.usage.docencoding.description=\u51FA\u529B\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-doclet.xusage.xdocrootparent.name=Xdocrootparent
-doclet.xusage.xdocrootparent.parameters=<url>
-doclet.xusage.xdocrootparent.description=doc\u30B3\u30E1\u30F3\u30C8\u5185\u306E/..\u304C\u5F8C\u306B\u7D9A\u304F@docRoot\u306E\u3059\u3079\u3066\u3092<url>\u3067\u7F6E\u63DB\u3057\u307E\u3059
+doclet.usage.frames.description=\u751F\u6210\u3055\u308C\u305F\u51FA\u529B\u3067\u30D5\u30EC\u30FC\u30E0\u306E\u4F7F\u7528\u3092\u6709\u52B9\u306B\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)
 
-doclet.xusage.xdoclint.name=Xdoclint
-doclet.xusage.xdoclint.description=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u63A8\u5968\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3057\u307E\u3059
+doclet.usage.no-frames.description=\u751F\u6210\u3055\u308C\u305F\u51FA\u529B\u3067\u30D5\u30EC\u30FC\u30E0\u306E\u4F7F\u7528\u3092\u7121\u52B9\u306B\u3057\u307E\u3059
+
+doclet.usage.xdocrootparent.parameters=<url>
+doclet.usage.xdocrootparent.description=doc\u30B3\u30E1\u30F3\u30C8\u5185\u306E/..\u304C\u5F8C\u306B\u7D9A\u304F@docRoot\u306E\u3059\u3079\u3066\u3092<url>\u3067\u7F6E\u63DB\u3057\u307E\u3059
 
-doclet.xusage.xdoclint-extended.name=Xdoclint:
-doclet.xusage.xdoclint-extended.parameters=(all|none|[-]<group>)
+doclet.usage.xdoclint.description=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u63A8\u5968\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3057\u307E\u3059
+
+doclet.usage.xdoclint-extended.parameters=(all|none|[-]<group>)
 # L10N: do not localize these words: all none accessibility html missing reference syntax
-doclet.xusage.xdoclint-extended.description=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\n                                  \u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n                                  \u3053\u3053\u3067\u3001<group>\u306Faccessibility\u3001html\u3001\n                                  missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002\n
+doclet.usage.xdoclint-extended.description=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\n                                  \u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n                                  \u3053\u3053\u3067\u3001<group>\u306Faccessibility\u3001html\u3001\nmissing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002
 
-doclet.xusage.xdoclint-package.name=Xdoclint/package:
-doclet.xusage.xdoclint-package.parameters=([-]<packages>)
-doclet.xusage.xdoclint-package.description=\n                                  \u7279\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002<packages>\u306F\n        \u30AB\u30F3\u30DE\u3067\u533A\u5207\u3089\u308C\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306F\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\n        \u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u3001\u307E\u305F\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306E\u63A5\u982D\u8F9E\u306E\u5F8C\u306B.*'\u6307\u5B9A(\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\n        \u3059\u3079\u3066\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u62E1\u5F35)\u3057\u305F\u3082\u306E\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u524D\u306B-\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\n        \u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u95A2\u3059\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u7121\u52B9\u306B\u3067\u304D\u307E\u3059\u3002\n
+doclet.usage.xdoclint-package.parameters=([-]<packages>)
+doclet.usage.xdoclint-package.description=\u7279\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002<packages>\u306F\n\u30AB\u30F3\u30DE\u3067\u533A\u5207\u3089\u308C\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\n\u6307\u5B9A\u5B50\u306F\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u3001\u307E\u305F\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\n\u306E\u63A5\u982D\u8F9E\u306E\u5F8C\u306B.*\u3092\u6307\u5B9A(\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u3059\u3079\u3066\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\n\u306B\u62E1\u5F35)\u3057\u305F\u3082\u306E\u3067\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6307\u5B9A\u5B50\u306E\u524D\u306B-\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\n\u6307\u5B9A\u3057\u305F\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u95A2\u3059\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u7121\u52B9\u306B\u3067\u304D\u307E\u3059\u3002
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -31,6 +31,11 @@
 doclet.Href_Class_Or_Interface_Title={0}\u4E2D\u7684\u7C7B\u6216\u63A5\u53E3
 doclet.Summary=\u6982\u8981:
 doclet.Detail=\u8BE6\u7EC6\u8D44\u6599:
+doclet.Module_Sub_Nav=\u6A21\u5757:
+doclet.navModuleDescription=\u8BF4\u660E
+doclet.navModules=\u6A21\u5757
+doclet.navPackages=\u7A0B\u5E8F\u5305
+doclet.navServices=\u670D\u52A1
 doclet.navNested=\u5D4C\u5957
 doclet.navAnnotationTypeOptionalMember=\u53EF\u9009
 doclet.navAnnotationTypeRequiredMember=\u5FC5\u9700
@@ -57,6 +62,7 @@
 doclet.Static_method_in={0}\u4E2D\u7684\u9759\u6001\u65B9\u6CD5
 doclet.Search_tag_in={0}\u4E2D\u7684\u641C\u7D22\u6807\u8BB0
 doclet.Method_in={0}\u4E2D\u7684\u65B9\u6CD5
+doclet.module=\u6A21\u5757
 doclet.package=\u7A0B\u5E8F\u5305
 doclet.MalformedURL=\u683C\u5F0F\u9519\u8BEF\u7684 URL: {0}
 doclet.File_error=\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519: {0}
@@ -91,7 +97,6 @@
 doclet.deprecated_annotation_type_members=\u5DF2\u8FC7\u65F6\u7684\u6CE8\u91CA\u7C7B\u578B\u5143\u7D20
 doclet.Generated_Docs_Untitled=\u751F\u6210\u7684\u6587\u6863 (\u65E0\u6807\u9898)
 doclet.Other_Packages=\u5176\u4ED6\u7A0B\u5E8F\u5305
-doclet.Package_Description=\u7A0B\u5E8F\u5305{0}\u7684\u8BF4\u660E
 doclet.Description=\u8BF4\u660E
 doclet.Specified_By=\u6307\u5B9A\u8005:
 doclet.in_interface=\u5728\u63A5\u53E3\u4E2D
@@ -183,159 +188,121 @@
 doclet.Error_in_packagelist=\u4F7F\u7528 -group \u9009\u9879\u65F6\u51FA\u9519: {0} {1}
 doclet.Groupname_already_used=\u5728 -group \u9009\u9879\u4E2D, groupname \u5DF2\u4F7F\u7528: {0}
 doclet.Same_package_name_used=\u7A0B\u5E8F\u5305\u540D\u79F0\u5F62\u5F0F\u4F7F\u7528\u4E86\u4E24\u6B21: {0}
-doclet.exception_encountered=\u5904\u7406{1}\u65F6\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\n{0}
 
 # option specifiers
-doclet.usage.d.name=d
 doclet.usage.d.parameters=<directory>
 doclet.usage.d.description=\u8F93\u51FA\u6587\u4EF6\u7684\u76EE\u6807\u76EE\u5F55
 
-doclet.usage.use.name=use
 doclet.usage.use.description=\u521B\u5EFA\u7C7B\u548C\u7A0B\u5E8F\u5305\u7528\u6CD5\u9875\u9762
 
-doclet.usage.version.name=version
 doclet.usage.version.description=\u5305\u542B @version \u6BB5
 
-doclet.usage.author.name=author
 doclet.usage.author.description=\u5305\u542B @author \u6BB5
 
-doclet.usage.docfilessubdirs.name=docfilessubdirs
 doclet.usage.docfilessubdirs.description=\u9012\u5F52\u590D\u5236\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55
 
-doclet.usage.splitindex.name=splitindex
 doclet.usage.splitindex.description=\u5C06\u7D22\u5F15\u5206\u4E3A\u6BCF\u4E2A\u5B57\u6BCD\u5BF9\u5E94\u4E00\u4E2A\u6587\u4EF6
 
-doclet.usage.windowtitle.name=windowtitle
-doclet.usage.windotitle.parameters=<text>
+doclet.usage.overview.parameters=<file>
+doclet.usage.overview.description=\u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863
+
+doclet.usage.windowtitle.parameters=<text>
 doclet.usage.windowtitle.description=\u6587\u6863\u7684\u6D4F\u89C8\u5668\u7A97\u53E3\u6807\u9898
 
-doclet.usage.doctitle.name=doctitle
 doclet.usage.doctitle.parameters=<html-code>
 doclet.usage.doctitle.description=\u5305\u542B\u6982\u89C8\u9875\u9762\u7684\u6807\u9898
 
-doclet.usage.header.name=\u9875\u7709
 doclet.usage.header.parameters=<html-code>
 doclet.usage.header.description=\u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u7709\u6587\u672C
 
-doclet.usage.html4.name=html4
 doclet.usage.html4.description=\u751F\u6210 HTML 4.01 \u8F93\u51FA
 
-doclet.usage.html5.name=html5
 doclet.usage.html5.description=\u751F\u6210 HTML 5 \u8F93\u51FA
 
-doclet.usage.footer.name=\u9875\u811A
 doclet.usage.footer.parameters=<html-code>
 doclet.usage.footer.description=\u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u811A\u6587\u672C
 
-doclet.usage.top.name=top
 doclet.usage.top.parameters=<html-code>
 doclet.usage.top.description=\u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9876\u90E8\u6587\u672C
 
-doclet.usage.bottom.name=bottom
 doclet.usage.bottom.parameters=<html-code>
 doclet.usage.bottom.description=\u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u5E95\u90E8\u6587\u672C
 
-doclet.usage.link.name=link
 doclet.usage.link.parameters=<url>
 doclet.usage.link.description=\u521B\u5EFA\u6307\u5411 <url> \u4E2D\u7684 javadoc \u8F93\u51FA\u7684\u94FE\u63A5
 
-doclet.usage.linkoffline.name=linkoffline
 doclet.usage.linkoffline.parameters=<url1> <url2>
 doclet.usage.linkoffline.description=\u4F7F\u7528 <url2> \u4E2D\u7684\u7A0B\u5E8F\u5305\u5217\u8868\u94FE\u63A5\u5230 <url1> \u4E2D\u7684\u6587\u6863
 
-doclet.usage.excludedocfilessubdir.name=excludedocfilessubdir
 doclet.usage.excludedocfilessubdir.parameters=<name>:..
-doclet.usage.excludedocfilessubdir.description=\n                                  \u6392\u9664\u5177\u6709\u7ED9\u5B9A\u540D\u79F0\u7684\u6240\u6709\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55
+doclet.usage.excludedocfilessubdir.description=\u6392\u9664\u5177\u6709\u7ED9\u5B9A\u540D\u79F0\u7684\u6240\u6709\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55
 
-doclet.usage.group.name=group
 doclet.usage.group.parameters=<name> <p1>:<p2>..
 doclet.usage.group.description=\u5C06\u6307\u5B9A\u7684\u7A0B\u5E8F\u5305\u5728\u6982\u89C8\u9875\u9762\u4E0A\u5206\u7EC4\u5728\u4E00\u8D77
 
-doclet.usage.nocomment.name=nocomment
 doclet.usage.nocomment.description=\u4E0D\u751F\u6210\u8BF4\u660E\u548C\u6807\u8BB0, \u53EA\u751F\u6210\u58F0\u660E
 
-doclet.usage.nodeprecated.name=nodeprecated
 doclet.usage.nodeprecated.description=\u4E0D\u5305\u542B @deprecated \u4FE1\u606F
 
-doclet.usage.noqualifier.name=noqualifier
 doclet.usage.noqualifier.parameters=<name1>:<name2>:..
 doclet.usage.noqualifier.description=\u8F93\u51FA\u4E2D\u4E0D\u5305\u62EC\u9650\u5B9A\u7B26\u7684\u5217\u8868
 
-doclet.usage.nosince.name=nosince
 doclet.usage.nosince.description=\u4E0D\u5305\u62EC @since \u4FE1\u606F
 
-doclet.usage.notimestamp.name=notimestamp
 doclet.usage.notimestamp.description=\u4E0D\u5305\u62EC\u9690\u85CF\u7684\u65F6\u95F4\u6233
 
-doclet.usage.nodeprecatedlist.name=nodeprecatedlist
 doclet.usage.nodeprecatedlist.description=\u4E0D\u751F\u6210\u5DF2\u8FC7\u65F6\u7684\u5217\u8868
 
-doclet.usage.notree.name=notree
 doclet.usage.notree.description=\u4E0D\u751F\u6210\u7C7B\u5206\u5C42\u7ED3\u6784
 
-doclet.usage.noindex.name=noindex
 doclet.usage.noindex.description=\u4E0D\u751F\u6210\u7D22\u5F15
 
-doclet.usage.nohelp.name=nohelp
 doclet.usage.nohelp.description=\u4E0D\u751F\u6210\u5E2E\u52A9\u94FE\u63A5
 
-doclet.usage.nonavbar.name=nonavbar
 doclet.usage.nonavbar.description=\u4E0D\u751F\u6210\u5BFC\u822A\u680F
 
-doclet.usage.nooverview.name=nooverview
 doclet.usage.nooverview.description=\u4E0D\u751F\u6210\u6982\u89C8\u9875\u9762
 
-doclet.usage.serialwarn.name=serialwarn
 doclet.usage.serialwarn.description=\u751F\u6210\u6709\u5173 @serial \u6807\u8BB0\u7684\u8B66\u544A
 
-doclet.usage.tag.name=tag
 doclet.usage.tag.parameters=<name>:<locations>:<header>
-doclet.usage.tag.description=\n                                  \u6307\u5B9A\u5355\u4E2A\u53C2\u6570\u5B9A\u5236\u6807\u8BB0
+doclet.usage.tag.description=\u6307\u5B9A\u5355\u4E2A\u53C2\u6570\u5B9A\u5236\u6807\u8BB0
 
-doclet.usage.taglet.name=taglet
 doclet.usage.taglet.description=\u8981\u6CE8\u518C\u7684 Taglet \u7684\u5168\u9650\u5B9A\u540D\u79F0
 
-doclet.usage.tagletpath.name=tagletpath
 doclet.usage.tagletpath.description=Taglet \u7684\u8DEF\u5F84
 
-doclet.usage.charset.name=charset
 doclet.usage.charset.parameters=<charset>
 doclet.usage.charset.description=\u7528\u4E8E\u8DE8\u5E73\u53F0\u67E5\u770B\u751F\u6210\u7684\u6587\u6863\u7684\u5B57\u7B26\u96C6
 
-doclet.usage.helpfile.name=helpfile
 doclet.usage.helpfile.parameters=<file>
 doclet.usage.helpfile.description=\u5305\u542B\u5E2E\u52A9\u94FE\u63A5\u6240\u94FE\u63A5\u5230\u7684\u6587\u4EF6
 
-doclet.usage.linksource.name=linksource
 doclet.usage.linksource.description=\u4EE5 HTML \u683C\u5F0F\u751F\u6210\u6E90\u6587\u4EF6
 
-doclet.usage.sourcetab.name=sourcetab
 doclet.usage.sourcetab.parameters=<tab length>
 doclet.usage.sourcetab.description=\u6307\u5B9A\u6E90\u4E2D\u6BCF\u4E2A\u5236\u8868\u7B26\u5360\u636E\u7684\u7A7A\u683C\u6570
 
-doclet.usage.keywords.name=keywords
-doclet.usage.keywords.description=\u968F\u7A0B\u5E8F\u5305,\n                                  \u7C7B\u548C\u6210\u5458\u4FE1\u606F\u4E00\u8D77\u9644\u5E26 HTML \u5143\u6807\u8BB0
+doclet.usage.keywords.description=\u968F\u7A0B\u5E8F\u5305, \u7C7B\u548C\u6210\u5458\u4FE1\u606F\u4E00\u8D77\u9644\u5E26 HTML \u5143\u6807\u8BB0
 
-doclet.usage.stylesheetfile.name=stylesheetfile
 doclet.usage.stylesheetfile.parameters=<path>
 doclet.usage.stylesheetfile.description=\u7528\u4E8E\u66F4\u6539\u751F\u6210\u6587\u6863\u7684\u6837\u5F0F\u7684\u6587\u4EF6
 
-doclet.usage.docencoding.name=docencoding
 doclet.usage.docencoding.parameters=<name>
 doclet.usage.docencoding.description=\u6307\u5B9A\u8F93\u51FA\u7684\u5B57\u7B26\u7F16\u7801
 
-doclet.xusage.xdocrootparent.name=Xdocrootparent
-doclet.xusage.xdocrootparent.parameters=<url>
-doclet.xusage.xdocrootparent.description=\u5C06\u6587\u6863\u6CE8\u91CA\u4E2D\u51FA\u73B0\u7684\u6240\u6709\u540E\u8DDF /..\n                                  \u7684 @docRoot \u66FF\u6362\u4E3A <url>
+doclet.usage.frames.description=\u5141\u8BB8\u5728\u751F\u6210\u7684\u8F93\u51FA\u4E2D\u4F7F\u7528\u5E27 (\u9ED8\u8BA4\u503C)
 
-doclet.xusage.xdoclint.name=Xdoclint
-doclet.xusage.xdoclint.description=\u4E3A\n                                  javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u5EFA\u8BAE\u7684\u68C0\u67E5
+doclet.usage.no-frames.description=\u7981\u6B62\u5728\u751F\u6210\u7684\u8F93\u51FA\u4E2D\u4F7F\u7528\u5E27
+
+doclet.usage.xdocrootparent.parameters=<url>
+doclet.usage.xdocrootparent.description=\u5C06\u6587\u6863\u6CE8\u91CA\u4E2D\u51FA\u73B0\u7684\u6240\u6709\u540E\u8DDF /.. \u7684 @docRoot \u66FF\u6362\u4E3A\n<url>
 
-doclet.xusage.xdoclint-extended.name=Xdoclint:
-doclet.xusage.xdoclint-extended.parameters=(all|none|[-]<group>)
+doclet.usage.xdoclint.description=\u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u5EFA\u8BAE\u7684\u68C0\u67E5
+
+doclet.usage.xdoclint-extended.parameters=(all|none|[-]<group>)
 # L10N: do not localize these words: all none accessibility html missing reference syntax
-doclet.xusage.xdoclint-extended.description=\u9488\u5BF9 javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\n                                  \u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n                                  \u5176\u4E2D <\u7EC4> \u4E3A accessibility, html,\n                                  missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n
+doclet.usage.xdoclint-extended.description=\u9488\u5BF9 javadoc\n\u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\n                                  \u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n                                  \u5176\u4E2D <\u7EC4> \u4E3A accessibility, html,\nmissing, reference \u6216 syntax \u4E4B\u4E00\u3002
 
-doclet.xusage.xdoclint-package.name=Xdoclint/package:
-doclet.xusage.xdoclint-package.parameters=([-]<packages>)
-doclet.xusage.xdoclint-package.description=\n                                  \u5728\u7279\u5B9A\u7684\u7A0B\u5E8F\u5305\u4E2D\u542F\u7528\u6216\u7981\u7528\n                                  \u68C0\u67E5\u3002<\u7A0B\u5E8F\u5305> \u662F\u9017\u53F7\u5206\u9694\u7684\n                                  \u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u5217\u8868\u3002\n                                  \u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u662F\u7A0B\u5E8F\u5305\u7684\u9650\u5B9A\n                                  \u540D\u79F0\u6216\u7A0B\u5E8F\u5305\u540D\u79F0\u524D\u7F00\u540E\u8DDF .*, \n                                  \u5B83\u6269\u5C55\u5230\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u7684\n                                  \u6240\u6709\u5B50\u7A0B\u5E8F\u5305\u3002\u5728\u7A0B\u5E8F\u5305\n                                  \u8BF4\u660E\u7B26\u524D\u9762\u52A0\u4E0A - \u53EF\u4EE5\u4E3A\n                                  \u6307\u5B9A\u7A0B\u5E8F\u5305\u7981\u7528\u68C0\u67E5\u3002\n
+doclet.usage.xdoclint-package.parameters=([-]<packages>)
+doclet.usage.xdoclint-package.description=\u5728\u7279\u5B9A\u7684\u7A0B\u5E8F\u5305\u4E2D\u542F\u7528\u6216\u7981\u7528\u68C0\u67E5\u3002<\u7A0B\u5E8F\u5305>\n\u662F\u9017\u53F7\u5206\u9694\u7684\u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u5217\u8868\u3002\u7A0B\u5E8F\u5305\n\u8BF4\u660E\u7B26\u662F\u7A0B\u5E8F\u5305\u7684\u9650\u5B9A\u540D\u79F0\u6216\u7A0B\u5E8F\u5305\u540D\u79F0\n\u524D\u7F00\u540E\u8DDF .*, \u5B83\u6269\u5C55\u5230\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u7684\u6240\u6709\n\u5B50\u7A0B\u5E8F\u5305\u3002\u5728\u7A0B\u5E8F\u5305\u8BF4\u660E\u7B26\u524D\u9762\u52A0\u4E0A - \u53EF\u4EE5\n\u4E3A\u6307\u5B9A\u7A0B\u5E8F\u5305\u7981\u7528\u68C0\u67E5\u3002
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -14,15 +14,21 @@
 doclet.Option_doclint_no_qualifiers=\u30A2\u30AF\u30BB\u30B9\u4FEE\u98FE\u5B50\u306F-Xdoclint\u306E\u5F15\u6570\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
 doclet.Option_doclint_invalid_arg=-Xdoclint\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059
 doclet.Option_doclint_package_invalid_arg=-Xdoclint/package\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059
-doclet.exception_encountered= {0}\u3092\u691C\u51FA\n\t\u30D5\u30A1\u30A4\u30EB\u306E\u4F5C\u6210\u4E2D: {1}
-doclet.perform_copy_exception_encountered= \u30B3\u30D4\u30FC\u5B9F\u884C\u4E2D\u306B{0}\u3092\n\u691C\u51FA\u3057\u307E\u3057\u305F\u3002
+doclet.builder.exception.in.component=\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306E\u69CB\u7BC9\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\t({1})
+doclet.builder.unknown.component=doclet\u30D3\u30EB\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u3067\u4E0D\u660E\u306A\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u304C\u53C2\u7167\u3055\u308C\u3066\u3044\u307E\u3059: {0}
+doclet.error.initializing.dest.dir=\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u521D\u671F\u5316\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}
+doclet.exception.read.file=\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\t({1})
+doclet.exception.write.file=\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\t({1})
+doclet.exception.read.resource=\u30B7\u30B9\u30C6\u30E0\u30FB\u30EA\u30BD\u30FC\u30B9\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\t({1})
+doclet.internal.exception=\u5185\u90E8\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 \n\t({0})
+doclet.internal.report.bug=Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(http://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002
 doclet.File_not_found=\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}
 doclet.Copy_Overwrite_warning=\u30D5\u30A1\u30A4\u30EB{0}\u306F\u540C\u3058\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308B\u306E\u3067{1}\u306B\u30B3\u30D4\u30FC\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F...
 doclet.Copying_File_0_To_Dir_1=\u30D5\u30A1\u30A4\u30EB{0}\u3092\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{1}\u306B\u30B3\u30D4\u30FC\u4E2D...
 doclet.Copying_File_0_To_File_1=\u30D5\u30A1\u30A4\u30EB{0}\u3092\u30D5\u30A1\u30A4\u30EB{1}\u306B\u30B3\u30D4\u30FC\u4E2D...
 doclet.No_Public_Classes_To_Document=\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3059\u308Bpublic\u307E\u305F\u306Fprotected\u30AF\u30E9\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002
-doclet.destination_directory_not_directory_0=\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u306F\u3042\u308A\u307E\u305B\u3093
-doclet.destination_directory_not_writable_0=\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u66F8\u8FBC\u307F\u53EF\u80FD\u3067\u306F\u3042\u308A\u307E\u305B\u3093
+doclet.destination_directory_not_directory_0=\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3067\u306F\u3042\u308A\u307E\u305B\u3093: {0}
+doclet.destination_directory_not_writable_0=\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u66F8\u8FBC\u307F\u53EF\u80FD\u3067\u306F\u3042\u308A\u307E\u305B\u3093: {0}
 doclet.Encoding_not_supported=\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0{0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 doclet.Building_Tree=\u5168\u30D1\u30C3\u30B1\u30FC\u30B8\u3068\u30AF\u30E9\u30B9\u306E\u968E\u5C64\u30C4\u30EA\u30FC\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059...
 doclet.Building_Index=\u5168\u30D1\u30C3\u30B1\u30FC\u30B8\u3068\u30AF\u30E9\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059...
@@ -67,6 +73,10 @@
 doclet.tag_misuse={0}\u30BF\u30B0\u306F{1}\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5185\u3067\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u4F7F\u7528\u3067\u304D\u308B\u306E\u306F\u6B21\u306E\u30BF\u30A4\u30D7\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5185\u306E\u307F\u3067\u3059: {2}\u3002
 doclet.javafx_tag_misuse=\u30BF\u30B0@propertyGetter\u3001@propertySetter\u304A\u3088\u3073@propertyDescription\u306F\u3001JavaFX\u306E\u30D7\u30ED\u30D1\u30C6\u30A3getter\u3068setter\u306E\u307F\u3067\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
 doclet.Package_Summary=\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u6982\u8981
+doclet.Requires_Summary=\u5FC5\u8981
+doclet.Exported_Packages_Summary=\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3055\u308C\u305F\u30D1\u30C3\u30B1\u30FC\u30B8
+doclet.Uses_Summary=\u4F7F\u7528
+doclet.Provides_Summary=\u63D0\u4F9B
 doclet.Module_Summary=\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u6982\u8981
 doclet.Interface_Summary=\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306E\u6982\u8981
 doclet.Annotation_Types_Summary=\u6CE8\u91C8\u578B\u306E\u6982\u8981
@@ -91,6 +101,7 @@
 doclet.Packages=\u30D1\u30C3\u30B1\u30FC\u30B8
 doclet.packages=\u30D1\u30C3\u30B1\u30FC\u30B8
 doclet.modules=\u30E2\u30B8\u30E5\u30FC\u30EB
+doclet.types=\u30BF\u30A4\u30D7
 doclet.All_Classes=\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9
 doclet.All_Superinterfaces=\u3059\u3079\u3066\u306E\u30B9\u30FC\u30D1\u30FC\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9:
 doclet.All_Implemented_Interfaces=\u3059\u3079\u3066\u306E\u5B9F\u88C5\u3055\u308C\u305F\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9:
@@ -168,6 +179,7 @@
 doclet.subinterfaces=\u30B5\u30D6\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
 doclet.Modifier=\u4FEE\u98FE\u5B50
 doclet.Type=\u30BF\u30A4\u30D7
+doclet.Implementation=\u5B9F\u88C5:
 doclet.Types=\u30BF\u30A4\u30D7
 doclet.Members=\u30E1\u30F3\u30D0\u30FC
 doclet.SearchTags=SearchTags
@@ -187,12 +199,11 @@
 doclet.0_and_1={0}\u3068{1}
 
 #Documentation for Enums
-doclet.enum_values_doc.firstsentence=\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u914D\u5217\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\n\u8FD4\u3057\u307E\u3059\u3002
-doclet.enum_values_doc.body=\  \u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3088\u3046\u306B\u3057\u3066\u5B9A\u6570\u3092\u53CD\u5FA9\u3059\u308B\u305F\u3081\u306B\n\u4F7F\u7528\u3067\u304D\u307E\u3059:\n<pre>\nfor({0} c: {0}.values())\n&nbsp; System.out.println(c);\n</pre>
+doclet.enum_values_doc.fullbody=\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u914D\u5217\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u8FD4\u3057\u307E\u3059\u3002\n\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3088\u3046\u306B\u3057\u3066\u5B9A\u6570\u3092\u53CD\u5FA9\u3059\u308B\u305F\u3081\u306B\n\u4F7F\u7528\u3067\u304D\u307E\u3059:\n<pre>\nfor ({0} c : {0}.values())\n&nbsp;   System.out.println(c);\n</pre>
+
 doclet.enum_values_doc.return=\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u306E\u914D\u5217
 
-doclet.enum_valueof_doc.firstsentence=\u6307\u5B9A\u3057\u305F\u540D\u524D\u3092\u6301\u3064\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u8FD4\u3057\u307E\u3059\u3002
-doclet.enum_valueof_doc.body=\n\u6587\u5B57\u5217\u306F\u3001\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u5BA3\u8A00\u3059\u308B\u306E\u306B\u4F7F\u7528\u3057\u305F\u8B58\u5225\u5B50\u3068<i>\u6B63\u78BA\u306B</i>\n\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n(\u4F59\u5206\u306A\u7A7A\u767D\u6587\u5B57\u3092\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002)
+doclet.enum_valueof_doc.fullbody=\u6307\u5B9A\u3057\u305F\u540D\u524D\u3092\u6301\u3064\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u8FD4\u3057\u307E\u3059\u3002\n\u6587\u5B57\u5217\u306F\u3001\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u5BA3\u8A00\u3059\u308B\u306E\u306B\u4F7F\u7528\u3057\u305F\u8B58\u5225\u5B50\u3068<i>\u6B63\u78BA\u306B</i>\n\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002(\u4F59\u5206\u306A\u7A7A\u767D\u6587\u5B57\u3092\u542B\u3081\u308B\u3053\u3068\u306F\n\u3067\u304D\u307E\u305B\u3093\u3002)
 
 doclet.enum_valueof_doc.param_name=\u8FD4\u3055\u308C\u308B\u5217\u6319\u578B\u5B9A\u6570\u306E\u540D\u524D\u3002
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -14,15 +14,21 @@
 doclet.Option_doclint_no_qualifiers=-Xdoclint \u53C2\u6570\u4E0D\u5141\u8BB8\u4F7F\u7528\u8BBF\u95EE\u9650\u5B9A\u7B26
 doclet.Option_doclint_invalid_arg=-Xdoclint \u9009\u9879\u7684\u53C2\u6570\u65E0\u6548
 doclet.Option_doclint_package_invalid_arg=-Xdoclint/package \u9009\u9879\u7684\u53C2\u6570\u65E0\u6548
-doclet.exception_encountered= \u5C1D\u8BD5\u521B\u5EFA\u6587\u4EF6{1}\u65F6 \n\t\u9047\u5230{0}
-doclet.perform_copy_exception_encountered= \u6267\u884C\u590D\u5236\u65F6 \n\u9047\u5230{0}\u3002
+doclet.builder.exception.in.component=\u6784\u5EFA\u7EC4\u4EF6\u65F6\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF: {0}\n\t({1})
+doclet.builder.unknown.component=doclet \u5DE5\u4F5C\u7248\u672C\u6587\u4EF6\u4E2D\u5F15\u7528\u7684\u7EC4\u4EF6\u672A\u77E5: {0}
+doclet.error.initializing.dest.dir=\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\u65F6\u51FA\u9519: {0}
+doclet.exception.read.file=\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519: {0}\n\t({1})
+doclet.exception.write.file=\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519: {0}\n\t({1})
+doclet.exception.read.resource=\u8BFB\u53D6\u7CFB\u7EDF\u8D44\u6E90\u65F6\u51FA\u9519: {0}\n\t({1})
+doclet.internal.exception=\u51FA\u73B0\u5185\u90E8\u5F02\u5E38\u9519\u8BEF\u3002\n\t({0})
+doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002
 doclet.File_not_found=\u627E\u4E0D\u5230\u6587\u4EF6: {0}
 doclet.Copy_Overwrite_warning=\u672A\u5C06\u6587\u4EF6{0}\u590D\u5236\u5230 {1}, \u56E0\u4E3A\u73B0\u6709\u6587\u4EF6\u5177\u6709\u76F8\u540C\u540D\u79F0...
 doclet.Copying_File_0_To_Dir_1=\u6B63\u5728\u5C06\u6587\u4EF6{0}\u590D\u5236\u5230\u76EE\u5F55 {1}...
 doclet.Copying_File_0_To_File_1=\u6B63\u5728\u5C06\u6587\u4EF6{0}\u590D\u5236\u5230\u6587\u4EF6{1}...
 doclet.No_Public_Classes_To_Document=\u627E\u4E0D\u5230\u53EF\u4EE5\u6587\u6863\u5316\u7684\u516C\u5171\u6216\u53D7\u4FDD\u62A4\u7684\u7C7B\u3002
-doclet.destination_directory_not_directory_0=\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u76EE\u5F55 {0}
-doclet.destination_directory_not_writable_0=\u76EE\u6807\u76EE\u5F55\u4E0D\u53EF\u5199\u5165 {0}
+doclet.destination_directory_not_directory_0=\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u76EE\u5F55: {0}
+doclet.destination_directory_not_writable_0=\u76EE\u6807\u76EE\u5F55\u4E0D\u53EF\u5199: {0}
 doclet.Encoding_not_supported=\u4E0D\u652F\u6301\u7F16\u7801: {0}
 doclet.Building_Tree=\u6B63\u5728\u6784\u5EFA\u6240\u6709\u7A0B\u5E8F\u5305\u548C\u7C7B\u7684\u6811...
 doclet.Building_Index=\u6B63\u5728\u6784\u5EFA\u6240\u6709\u7A0B\u5E8F\u5305\u548C\u7C7B\u7684\u7D22\u5F15...
@@ -67,6 +73,10 @@
 doclet.tag_misuse=\u4E0D\u80FD\u5728{1}\u6587\u6863\u4E2D\u4F7F\u7528\u6807\u8BB0{0}\u3002\u53EA\u80FD\u5728\u4EE5\u4E0B\u7C7B\u578B\u7684\u6587\u6863\u4E2D\u4F7F\u7528\u8BE5\u6807\u8BB0: {2}\u3002
 doclet.javafx_tag_misuse=\u6807\u8BB0 @propertyGetter, @propertySetter \u548C @propertyDescription \u53EA\u80FD\u5728 JavaFX \u5C5E\u6027 getter \u548C setter \u4E2D\u4F7F\u7528\u3002
 doclet.Package_Summary=\u7A0B\u5E8F\u5305\u6982\u8981
+doclet.Requires_Summary=\u5FC5\u9700\u9879
+doclet.Exported_Packages_Summary=\u5BFC\u51FA\u7684\u7A0B\u5E8F\u5305
+doclet.Uses_Summary=\u4F7F\u7528
+doclet.Provides_Summary=\u63D0\u4F9B
 doclet.Module_Summary=\u6A21\u5757\u6982\u8981
 doclet.Interface_Summary=\u63A5\u53E3\u6982\u8981
 doclet.Annotation_Types_Summary=\u6CE8\u91CA\u7C7B\u578B\u6982\u8981
@@ -91,6 +101,7 @@
 doclet.Packages=\u7A0B\u5E8F\u5305
 doclet.packages=\u7A0B\u5E8F\u5305
 doclet.modules=\u6A21\u5757
+doclet.types=\u7C7B\u578B
 doclet.All_Classes=\u6240\u6709\u7C7B
 doclet.All_Superinterfaces=\u6240\u6709\u8D85\u7EA7\u63A5\u53E3:
 doclet.All_Implemented_Interfaces=\u6240\u6709\u5DF2\u5B9E\u73B0\u7684\u63A5\u53E3:
@@ -168,6 +179,7 @@
 doclet.subinterfaces=\u5B50\u63A5\u53E3
 doclet.Modifier=\u9650\u5B9A\u7B26
 doclet.Type=\u7C7B\u578B
+doclet.Implementation=\u5B9E\u73B0:
 doclet.Types=\u7C7B\u578B
 doclet.Members=\u6210\u5458
 doclet.SearchTags=\u641C\u7D22\u6807\u8BB0
@@ -187,12 +199,11 @@
 doclet.0_and_1={0}\u548C{1}
 
 #Documentation for Enums
-doclet.enum_values_doc.firstsentence=\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \n\u8FD4\u56DE\u4E00\u4E2A\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4\u3002
-doclet.enum_values_doc.body=\  \u8BE5\u65B9\u6CD5\u53EF\u7528\u4E8E\u8FED\u4EE3\n\u5E38\u91CF, \u5982\u4E0B\u6240\u793A:\n<pre>\nfor ({0} c : {0}.values())\n&nbsp;   System.out.println(c);\n</pre>
+doclet.enum_values_doc.fullbody=\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4\u3002\u8BE5\u65B9\u6CD5\u53EF\u7528\u4E8E\u8FED\u4EE3\n\u5E38\u91CF, \u5982\u4E0B\u6240\u793A:\n<pre>\nfor ({0} c : {0}.values())\n&nbsp;   System.out.println(c);\n</pre>
+
 doclet.enum_values_doc.return=\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F\u8FD4\u56DE\u7684\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4
 
-doclet.enum_valueof_doc.firstsentence=\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u3002
-doclet.enum_valueof_doc.body=\n\u5B57\u7B26\u4E32\u5FC5\u987B\u4E0E\u7528\u4E8E\u58F0\u660E\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u7684\n\u6807\u8BC6\u7B26<i>\u5B8C\u5168</i>\u5339\u914D\u3002(\u4E0D\u5141\u8BB8\u6709\u591A\u4F59\n\u7684\u7A7A\u683C\u5B57\u7B26\u3002)
+doclet.enum_valueof_doc.fullbody=\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u3002\n\u5B57\u7B26\u4E32\u5FC5\u987B\u4E0E\u7528\u4E8E\u58F0\u660E\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u7684\n\u6807\u8BC6\u7B26<i>\u5B8C\u5168</i>\u5339\u914D\u3002(\u4E0D\u5141\u8BB8\u6709\u591A\u4F59\n\u7684\u7A7A\u683C\u5B57\u7B26\u3002)
 
 doclet.enum_valueof_doc.param_name=\u8981\u8FD4\u56DE\u7684\u679A\u4E3E\u5E38\u91CF\u7684\u540D\u79F0\u3002
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -28,29 +28,146 @@
 main.warnings=\u8B66\u544A{0}\u500B
 main.warning=\u8B66\u544A{0}\u500B
 
-main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n  -overview <file>          HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n  -public                   public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n  -protected                protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n  -package                  package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n  -private                  \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n  -help                     \u30B3\u30DE\u30F3\u30C9\u884C\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n  -doclet <class>           \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n  -docletpath <path>        doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -modulesourcepath <path>         \u8907\u6570\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u5165\u529B\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -upgrademodulepath <path>        \u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  -modulepath <path>               \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -mp <path>                       \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -addmods <module>(,<module>)*    \u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F\n                                   <module>\u304CALL-MODULE-PATH\u3067\u3042\u308B\u5834\u5408\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3002\n  -limitmods <module>(,<module>)*  \u76E3\u8996\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30E6\u30CB\u30D0\u30FC\u30B9\u3092\u5236\u9650\u3059\u308B\n  -sourcepath <pathlist>    \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -classpath <pathlist>     \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -cp <pathlist>                   \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n  -exclude <pkglist>        \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n  -subpackages <subpkglist> \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n  -breakiterator            BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n  -bootclasspath <pathlist> \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30ED\u30FC\u30C0\u30FC\u306B\u3088\u308A\u30ED\u30FC\u30C9\u3055\u308C\u305F\n                                   \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  -source <release>         \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n  -extdirs <dirlist>        \
-\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n  -verbose                  Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n  -locale <name>            en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n  -encoding <name>          \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n  -quiet                    \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n  -J<flag>                  <flag>\u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n  -X                        \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u7D42\u4E86\u3059\u308B\n
+main.usage=\u4F7F\u7528\u65B9\u6CD5:\n    javadoc [options] [packagenames] [sourcefiles] [@files]\n\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:
+
+main.opt.public.desc=public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B
+
+main.opt.protected.desc=protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u3092\u8868\u793A\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)
+
+main.opt.package.desc=package/protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u3092\u8868\u793A\u3059\u308B
+
+main.opt.private.desc=\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u3092\u8868\u793A\u3059\u308B
+
+main.opt.show.members.arg=<value>
+main.opt.show.members.desc=\u5024\u304C"public"\u3001"protected"\u3001"package"\u307E\u305F\u306F"private"\u306E\u3044\u305A\u308C\u304B\u306E\n\u3069\u306E\u30E1\u30F3\u30D0\u30FC(\u30D5\u30A3\u30FC\u30EB\u30C9\u3084\u30E1\u30BD\u30C3\u30C9\u306A\u3069)\u3092\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3059\u308B\u304B\u3092\u6307\u5B9A\u3059\u308B\u3002\n\u30C7\u30D5\u30A9\u30EB\u30C8\u306F"protected"\u3067\u3001public\u304A\u3088\u3073protected\u30E1\u30F3\u30D0\u30FC\u304C\u8868\u793A\u3055\u308C\u3001\n"public"\u3067\u306Fpublic\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002"package"\u3067\u306F\npublic\u3001protected\u304A\u3088\u3073package\u30E1\u30F3\u30D0\u30FC\u304C\u8868\u793A\u3055\u308C\u3001"private"\n\u3067\u306F\u3059\u3079\u3066\u306E\u30E1\u30F3\u30D0\u30FC\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002
+
+main.opt.show.types.arg=<value>
+main.opt.show.types.desc=\u5024\u304C"public"\u3001"protected"\u3001"package"\u307E\u305F\u306F"private"\u306E\u3044\u305A\u308C\u304B\u306E\n\u3069\u306E\u578B(\u30AF\u30E9\u30B9\u3084\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306A\u3069)\u3092\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3059\u308B\u304B\u3092\u6307\u5B9A\u3059\u308B\u3002\n\u30C7\u30D5\u30A9\u30EB\u30C8\u306F"protected"\u3067\u3001public\u304A\u3088\u3073protected\u578B\u304C\u8868\u793A\u3055\u308C\u3001\n"public"\u3067\u306Fpublic\u578B\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002"package"\u3067\u306F\npublic\u3001protected\u304A\u3088\u3073package\u578B\u304C\u8868\u793A\u3055\u308C\u3001"private"\n\u3067\u306F\u3059\u3079\u3066\u306E\u578B\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002
+
+main.opt.show.packages.arg=<value>
+main.opt.show.packages.desc=\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3059\u308B\u304B\u3092\u6307\u5B9A\u3059\u308B\u3002\u4F7F\u7528\u53EF\u80FD\u306A\n\u5024\u306F\u3001"exported"\u307E\u305F\u306F"all"\u30D1\u30C3\u30B1\u30FC\u30B8\u3067\u3059\u3002
+
+main.opt.show.module.contents.arg=<value>
+main.opt.show.module.contents.desc=\u30E2\u30B8\u30E5\u30FC\u30EB\u5BA3\u8A00\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u306E\u7C92\u5EA6\u3092\u6307\u5B9A\u3059\u308B\u3002\n\u4F7F\u7528\u53EF\u80FD\u306A\u5024\u306F\u3001"api"\u307E\u305F\u306F"all"\u3067\u3059\u3002
+
+main.opt.expand.requires.arg=<value>
+main.opt.expand.requires.desc=\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30BB\u30C3\u30C8\u3092\u62E1\u5F35\u3059\u308B\u305F\u3081\u306E\n\u30C4\u30FC\u30EB\u3092\u6307\u5B9A\u3059\u308B\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u3067\u660E\u793A\u7684\u306B\n\u6307\u5B9A\u3055\u308C\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u307F\u304C\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3055\u308C\u307E\u3059\u3002"public"\u306E\u5024\u306F\u3001\n\u305D\u308C\u3089\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u3059\u3079\u3066\u306E"requires public"\u4F9D\u5B58\u6027\u3092\u8FFD\u52A0\u3067\n\u542B\u3081\u307E\u3059\u3002"all"\u306E\u5024\u306F\u3001\u305D\u308C\u3089\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\n\u542B\u3081\u307E\u3059\u3002
+
+main.opt.help.desc=\u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B
+
+main.opt.module.arg=<module>(,<module>)*
+main.opt.module.desc=\u6307\u5B9A\u3055\u308C\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5316\u3059\u308B
+
+main.opt.doclet.arg=<class>
+main.opt.doclet.desc=\u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B
+
+main.opt.docletpath.arg=<path>
+main.opt.docletpath.desc=doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.module.source.path.arg=<path>
+main.opt.module.source.path.desc=\u8907\u6570\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u5165\u529B\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u4F4D\u7F6E\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.upgrade.module.path.arg=<path>
+main.opt.upgrade.module.path.desc=\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u4F4D\u7F6E\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
+
+main.opt.module.path.arg=<path>
+main.opt.module.path.desc=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u4F4D\u7F6E\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.add.modules.arg=<module>(,<module>)*
+main.opt.add.modules.desc=\u521D\u671F\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\u52A0\u3048\u3066\u89E3\u6C7A\u3059\u308B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F\n<module>\u304CALL-MODULE-PATH\u3067\u3042\u308B\u5834\u5408\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306E\n\u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3002
+
+main.opt.limit.modules.arg=<module>(,<module>)*
+main.opt.limit.modules.desc=\u53C2\u7167\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u9818\u57DF\u3092\u5236\u9650\u3057\u307E\u3059
+
+main.opt.source.path.arg=<path>
+main.opt.source.path.desc=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.class.path.arg=<path>
+main.opt.class.path.desc=\u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.exclude.arg=<pkglist>
+main.opt.exclude.desc=\u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B
 
-main.Xusage=\  -Xmaxerrs <number>               \u51FA\u529B\u3059\u308B\u6700\u5927\u30A8\u30E9\u30FC\u6570\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n  -Xmaxwarns <number>              \u51FA\u529B\u3059\u308B\u6700\u5927\u8B66\u544A\u6570\u3092\u8A2D\u5B9A\u3057\u307E\u3059\n  -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n                                   \u305D\u306E\u5B9A\u7FA9\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\u3001\u8FFD\u52A0\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F<other-module>\u304C\n                                   ALL-UNNAMED\u3067\u3042\u308B\u5834\u5408\u306F\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\n                                   \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u6E08\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n  -XaddReads:<module>=<other-module>(,<other-module>)*\n                                   \u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u5FC5\u9808\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n                                   \u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u5834\u5408\u3001<other-module>\u306FALL-UNNAMED\n                                   \u306B\u3057\u307E\u3059\u3002\n  -Xmodule:<module-name>           \u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u304C\u5C5E\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n  -Xpatch:<module>=<file>(:<file>)*\n                                   JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n                                   \u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3057\u307E\u3059\n  -Xold                            \u65E7\u5F0F\u306Ejavadoc\u30C4\u30FC\u30EB\u3092\u8D77\u52D5\u3057\u307E\u3059\n
+main.opt.subpackages.arg=<subpkglist>
+main.opt.subpackages.desc=\u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.breakiterator.desc=BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B
+
+main.opt.bootclasspath.arg=<path>
+main.opt.bootclasspath.desc=\u975E\u30E2\u30B8\u30E5\u30E9\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u4F7F\u7528\u3055\u308C\u308B\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\n\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
+
+main.opt.system.arg=<jdk>
+main.opt.system.desc=\u30E2\u30B8\u30E5\u30E9\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u4F7F\u7528\u3055\u308C\u308B\u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
+
+main.opt.release.arg=<release>
+main.opt.release.desc=\u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u4FDD\u3064
+
+main.opt.source.arg=<release>
+main.opt.source.desc=\u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u4FDD\u3064
+
+main.opt.extdirs.arg=<dirlist>
+main.opt.extdirs.desc=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u6E08\u307F\u62E1\u5F35\u6A5F\u80FD\u306E\u4F4D\u7F6E\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
+
+main.opt.verbose.desc=Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B
+
+main.opt.locale.arg=<name>
+main.opt.locale.desc=en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB
+
+main.opt.encoding.arg=<name>
+main.opt.encoding.desc=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D
+
+main.opt.quiet.desc=\u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044
 
-main.Xusage.foot=\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
+main.opt.J.arg=<flag>
+main.opt.J.desc=<flag>\u3092\u5B9F\u884C\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059
+
+main.opt.X.desc=\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u7D42\u4E86\u3059\u308B
+
+main.usage.foot=\nGNU\u30B9\u30BF\u30A4\u30EB\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u306F\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u540D\u524D\u3068\u305D\u306E\u5024\u3092\u533A\u5207\u308B\u305F\u3081\u306B\u7A7A\u767D\u3067\u306F\u306A\u304F'='\u3092\n\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n
+
+main.Xusage=
+
+main.opt.Xmaxerrs.arg=<number>
+main.opt.Xmaxerrs.desc=\u51FA\u529B\u3059\u308B\u30A8\u30E9\u30FC\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B
+
+main.opt.Xmaxwarns.arg=<number>
+main.opt.Xmaxwarns.desc=\u51FA\u529B\u3059\u308B\u8B66\u544A\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B
 
-main.doclet.usage.header={0} doclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:
+main.opt.add.exports.arg=<module>/<package>=<other-module>(,<other-module>)*
+main.opt.add.exports.desc=\u305D\u306E\u5B9A\u7FA9\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\u3001\u8FFD\u52A0\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F<other-module>\u304C\nALL-UNNAMED\u3067\u3042\u308B\u5834\u5408\u306F\u3059\u3079\u3066\u306E\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u306B\n\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u6E08\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3057\u307E\u3059
+
+main.opt.add.reads.arg=<module>=<other-module>(,<other-module>)*
+main.opt.add.reads.desc=\u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u5FC5\u9808\u3068\u307F\u306A\u3055\u308C\u308B\u3088\u3046\u306B\u8FFD\u52A0\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n\u540D\u524D\u306E\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5FC5\u8981\u3068\u3059\u308B\u5834\u5408\u3001<other-module>\u306FALL-UNNAMED\n\u306B\u3057\u307E\u3059\u3002
+
+main.opt.Xmodule.arg=<module-name>
+main.opt.Xmodule.desc=\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u304C\u5C5E\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059
+
+main.opt.patch.module.arg=<module>=<file>(:<file>)*
+main.opt.patch.module.desc=JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30EA\u30BD\u30FC\u30B9\u3067\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\n        \u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u307E\u305F\u306F\u62E1\u5F35\u3057\u307E\u3059
+
+main.opt.Xold.desc=\u65E7\u5F0F\u306Ejavadoc\u30C4\u30FC\u30EB\u3092\u8D77\u52D5\u3059\u308B
+
+main.Xusage.foot=\n\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
+
+main.doclet.usage.header=\n{0} doclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:
 
 main.requires_argument=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3059\u3002
+main.unnecessary_arg_provided=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306F\u5F15\u6570\u3092\u5FC5\u8981\u3068\u3057\u307E\u305B\u3093
+main.only_one_argument_with_equals=\u8907\u6570\u306E\u5F15\u6570\u3092\u5FC5\u8981\u3068\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306B''=''\u69CB\u6587\u3092\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093
 main.invalid_flag={0}\u306F\u7121\u52B9\u306A\u30D5\u30E9\u30B0\u3067\u3059
-main.No_packages_or_classes_specified=\u30D1\u30C3\u30B1\u30FC\u30B8\u307E\u305F\u306F\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
-main.incompatible.access.flags=-public\u3001-private\u3001-package\u307E\u305F\u306F-protected\u306E\u3046\u3061\u306E2\u3064\u4EE5\u4E0A\u3092\u6307\u5B9A\u3057\u307E\u3057\u305F\u3002
+main.No_modules_packages_or_classes_specified=\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u307E\u305F\u306F\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
+main.module_not_found=\u30E2\u30B8\u30E5\u30FC\u30EB{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\n
 main.cant.read={0}\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093
 main.Loading_source_files_for_package=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306E\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u8FBC\u3093\u3067\u3044\u307E\u3059...
 main.Loading_source_file=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB{0}\u3092\u8AAD\u307F\u8FBC\u3093\u3067\u3044\u307E\u3059...
 main.Building_tree=Javadoc\u60C5\u5831\u3092\u69CB\u7BC9\u3057\u3066\u3044\u307E\u3059...
 main.no_source_files_for_package=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306E\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093
-main.fatal.error=\u81F4\u547D\u7684\u30A8\u30E9\u30FC
-main.fatal.exception=\u81F4\u547D\u7684\u4F8B\u5916
+main.package_not_found=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F
+main.fatal.error=\u81F4\u547D\u7684\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}
 main.out.of.memory=java.lang.OutOfMemoryError: \u30E1\u30E2\u30EA\u30FC\u3092\u5897\u3084\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u305F\u3068\u3048\u3070\u3001JDK\u306Eclassic\u3082\u3057\u304F\u306Fhotspot VM\u3067\u306F\u3001-J-Xmx32m\u306E\u3088\u3046\u306B\n-J-Xmx\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
 main.done_in=[{0}\u30DF\u30EA\u79D2\u3067\u5B8C\u4E86]
 main.more_than_one_doclet_specified_0_and_1=\u8907\u6570\u306Edoclet({0}\u3068{1})\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002
+main.doclet_could_not_get_location={0}\u306E\u5834\u6240\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
 main.doclet_could_not_set_location={0}\u306E\u5834\u6240\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
 main.doclet_no_classloader_found={0}\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
 main.could_not_instantiate_class=\u30AF\u30E9\u30B9{0}\u3092\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u5316\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
@@ -61,10 +178,16 @@
 main.file_ignored=\u30D5\u30A1\u30A4\u30EB\u306F\u7121\u8996\u3055\u308C\u307E\u3057\u305F: "{0}" (\u307E\u3060\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093)
 main.illegal_class_name=\u30AF\u30E9\u30B9\u540D\u304C\u4E0D\u6B63\u3067\u3059: "{0}"
 main.illegal_package_name=\u30D1\u30C3\u30B1\u30FC\u30B8\u540D"{0}"\u306F\u4E0D\u6B63\u3067\u3059
+main.illegal_option_value=\u4E0D\u6B63\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u5024: "{0}"
 main.release.bootclasspath.conflict=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306F-release\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
 main.unsupported.release.version=\u30EA\u30EA\u30FC\u30B9\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3{0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 main.release.not.standard.file.manager=-release\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u6307\u5B9A\u3055\u308C\u305FJavaFileManager\u306FStandardJavaFileManager\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
+main.file.manager.list=\u30D5\u30A1\u30A4\u30EB\u306E\u30EA\u30B9\u30C8\u4E2D\u306EFileManager\u30A8\u30E9\u30FC: "{0}"
+main.assertion.error=\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u304C\u5931\u6557\u3057\u307E\u3057\u305F: "{0}}"
 main.unknown.error=\u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
+main.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
+main.unexpected.exception=\u4E88\u671F\u3057\u306A\u3044\u4F8B\u5916\u304C\u6355\u6349\u3055\u308C\u307E\u3057\u305F: {0}
+doclet.internal.report.bug=Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(http://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002
 main.legacy_api=\u30D1\u30C3\u30B1\u30FC\u30B8com.sun.javadoc\u3001com.sun.tools.doclets\u304A\u3088\u3073\n\u305D\u308C\u3089\u306E\u5B9F\u88C5\u5185\u306E\u53E4\u3044Doclet\u304A\u3088\u3073Taglet API\u306F\u3001\n\u4ECA\u5F8C\u306EJDK\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059\u3002\u3053\u308C\u3089\u306E\n\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306Fjdk.javadoc.doclet\u306E\u65B0\u3057\u3044API\u306B\u3088\u3063\u3066\u7F6E\u304D\u63DB\u3048\u3089\u308C\u307E\u3057\u305F\u3002\n\u30E6\u30FC\u30B6\u30FC\u306B\u306F\u65B0\u3057\u3044API\u306B\u79FB\u884C\u3059\u308B\u3053\u3068\u3092\u5F37\u304F\u304A\u85A6\u3081\u3057\u307E\u3059\u3002\n
 
 javadoc.class_not_found=\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -28,42 +28,166 @@
 main.warnings={0} \u4E2A\u8B66\u544A
 main.warning={0} \u4E2A\u8B66\u544A
 
-main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n  -overview <\u6587\u4EF6>                 \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n  -public                          \u4EC5\u663E\u793A public \u7C7B\u548C\u6210\u5458\n  -protected                       \u663E\u793A protected/public \u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n  -package                         \u663E\u793A package/protected/public \u7C7B\u548C\u6210\u5458\n  -private                         \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n  -help                            \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n  -doclet <\u7C7B>                     \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n  -docletpath <\u8DEF\u5F84>               \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -modulesourcepath <\u8DEF\u5F84>         \u6307\u5B9A\u67E5\u627E\u591A\u4E2A\u6A21\u5757\u7684\u8F93\u5165\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -upgrademodulepath <\u8DEF\u5F84>        \u8986\u76D6\u53EF\u5347\u7EA7\u6A21\u5757\u4F4D\u7F6E\n  -modulepath <\u8DEF\u5F84>               \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E\n  -mp <\u8DEF\u5F84>                       \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E\n  -addmods <\u6A21\u5757>(,<\u6A21\u5757>)*        \u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757; \u5982\u679C <\u6A21\u5757>\n                                   \u4E3A ALL-MODULE-PATH, \u5219\u4E3A\u6A21\u5757\u8DEF\u5F84\u4E2D\u7684\u6240\u6709\u6A21\u5757\u3002\n  -limitmods <\u6A21\u5757>(,<\u6A21\u5757>)*      \u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF\n  -sourcepath <\u8DEF\u5F84\u5217\u8868>           \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -classpath <\u8DEF\u5F84\u5217\u8868>            \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -cp <\u8DEF\u5F84\u5217\u8868>                   \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -exclude <\u7A0B\u5E8F\u5305\u5217\u8868>            \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n  -subpackages <\u5B50\u7A0B\u5E8F\u5305\u5217\u8868>      \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n  -breakiterator                   \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n  -bootclasspath <\u8DEF\u5F84\u5217\u8868>        \u8986\u76D6\u7531\u5F15\u5BFC\u7C7B\u52A0\u8F7D\u5668\u6240\u52A0\u8F7D\u7684\n                                   \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n  -source <\u53D1\u884C\u7248>                 \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n  -extdirs <\u76EE\u5F55\u5217\u8868>              \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n  -verbose                         \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u4FE1\u606F\n  -locale <\u540D\u79F0>                   \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n  -encoding <\u540D\u79F0>                 \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n  -quiet                           \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n  -J<\u6807\u8BB0>                         \u76F4\u63A5\u5C06 <\u6807\u8BB0> \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n  -X                               \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\u5E76\u9000\u51FA\n
+main.usage=\u7528\u6CD5:\n    javadoc [options] [packagenames] [sourcefiles] [@files]\n\u5176\u4E2D, \u9009\u9879\u5305\u62EC:
+
+main.opt.public.desc=\u4EC5\u663E\u793A\u516C\u5171\u7C7B\u548C\u6210\u5458
+
+main.opt.protected.desc=\u663E\u793A\u53D7\u4FDD\u62A4/\u516C\u5171\u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)
+
+main.opt.package.desc=\u663E\u793A\u7A0B\u5E8F\u5305/\u53D7\u4FDD\u62A4/\u516C\u5171\u7C7B\u548C\u6210\u5458
+
+main.opt.private.desc=\u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458
+
+main.opt.show.members.arg=<\u503C>
+main.opt.show.members.desc=\u6307\u5B9A\u5C06\u6587\u6863\u5316\u7684\u6210\u5458 (\u5B57\u6BB5, \u65B9\u6CD5\u7B49), \u5176\u503C\u53EF\u4EE5\n\u4E3A "public", "protected", "package" \u6216 \n"private" \u4E4B\u4E00\u3002\u9ED8\u8BA4\u503C\u4E3A "protected", \u8BE5\u503C\u5C06\n\u663E\u793A\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u6210\u5458, "public" \u5C06\u4EC5\u663E\u793A\n\u516C\u5171\u6210\u5458, "package" \u5C06\u663E\u793A\u516C\u5171, \u53D7\u4FDD\u62A4\u548C\n\u7A0B\u5E8F\u5305\u6210\u5458, "private" \u5C06\u663E\u793A\u6240\u6709\u6210\u5458\u3002
+
+main.opt.show.types.arg=<\u503C>
+main.opt.show.types.desc=\u6307\u5B9A\u5C06\u6587\u6863\u5316\u7684\u7C7B\u578B (\u7C7B, \u63A5\u53E3\u7B49), \u5176\u503C\u53EF\u4EE5\n\u4E3A "public", "protected", "package" \u6216 \n"private" \u4E4B\u4E00\u3002\u9ED8\u8BA4\u503C\u4E3A "protected", \u8BE5\u503C\u5C06\n\u663E\u793A\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u7C7B\u578B, "public" \u5C06\u4EC5\u663E\u793A\n\u516C\u5171\u7C7B\u578B, "package" \u5C06\u663E\u793A\u516C\u5171, \u53D7\u4FDD\u62A4\u548C\n\u7A0B\u5E8F\u5305\u7C7B\u578B, "private" \u5C06\u663E\u793A\u6240\u6709\u7C7B\u578B\u3002
+
+main.opt.show.packages.arg=<\u503C>
+main.opt.show.packages.desc=\u6307\u5B9A\u5C06\u6587\u6863\u5316\u7684\u6A21\u5757\u7684\u7A0B\u5E8F\u5305\u3002\n\u53EF\u80FD\u7684\u503C\u4E3A "exported" \u6216 "all" \u7A0B\u5E8F\u5305\u3002
+
+main.opt.show.module.contents.arg=<\u503C>
+main.opt.show.module.contents.desc=\u6307\u5B9A\u6A21\u5757\u58F0\u660E\u7684\u6587\u6863\u7C92\u5EA6\u3002\n\u53EF\u80FD\u7684\u503C\u4E3A "api" \u6216 "all"\u3002
+
+main.opt.expand.requires.arg=<\u503C>
+main.opt.expand.requires.desc=\u6307\u793A\u5DE5\u5177\u5C55\u5F00\u8981\u6587\u6863\u5316\u7684\u6A21\u5757\u96C6\u3002\n\u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u5C06\u4EC5\u6587\u6863\u5316\u547D\u4EE4\u884C\u4E2D\u660E\u786E\n\u6307\u5B9A\u7684\u6A21\u5757\u3002\u503C "public" \u5C06\u989D\u5916\u5305\u542B\n\u8FD9\u4E9B\u6A21\u5757\u7684\u6240\u6709 "requires public"\n\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\u503C "all" \u5C06\u5305\u542B\u8FD9\u4E9B\u6A21\u5757\n\u7684\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
+
+main.opt.help.desc=\u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA
+
+main.opt.module.arg=<\u6A21\u5757>(,<\u6A21\u5757>)*
+main.opt.module.desc=\u6587\u6863\u5316\u6307\u5B9A\u6A21\u5757
 
-main.Xusage=\  -Xmaxerrs <\u6570\u5B57>                 \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u9519\u8BEF\u7684\u6700\u5927\u6570\u76EE\n  -Xmaxwarns <\u6570\u5B57>                \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u8B66\u544A\u7684\u6700\u5927\u6570\u76EE\n  -XaddExports:<\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*\n                                   \u6307\u5B9A\u5C06\u7A0B\u5E8F\u5305\u89C6\u4E3A\u5DF2\u4ECE\u5176\u5B9A\u4E49\u6A21\u5757\u5BFC\u51FA\u5230\u5176\u4ED6\u6A21\u5757,\n                                   \u5982\u679C <\u5176\u4ED6\u6A21\u5757> \u4E3A ALL-UNNAMED, \u5219\u89C6\u4E3A\n                                   \u5BFC\u51FA\u5230\u6240\u6709\u672A\u547D\u540D\u6A21\u5757\u3002\n  -XaddReads:<\u6A21\u5757>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*\n                                   \u6307\u5B9A\u88AB\u89C6\u4E3A\u7ED9\u5B9A\u6A21\u5757\u9700\u8981\u7684\u5176\u4ED6\u6A21\u5757\u3002\n                                   <\u5176\u4ED6\u6A21\u5757> \u53EF\u4EE5\u4E3A ALL-UNNAMED \u4EE5\u4FBF\u8981\u6C42\n                                   \u672A\u547D\u540D\u6A21\u5757\u3002\n  -Xmodule:<\u6A21\u5757\u540D\u79F0>              \u6307\u5B9A\u6B63\u5728\u7F16\u8BD1\u7684\u7C7B\u6240\u5C5E\u7684\u6A21\u5757\u3002\n  -Xpatch:<\u6A21\u5757>=<\u6587\u4EF6>(:<\u6587\u4EF6>)*\n                                   \u4F7F\u7528 JAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\n                                   \u8986\u76D6\u6216\u589E\u5F3A\u6A21\u5757\n  -Xold                            \u8C03\u7528\u4F20\u7EDF javadoc \u5DE5\u5177\n
+main.opt.doclet.arg=<\u7C7B>
+main.opt.doclet.desc=\u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA
+
+main.opt.docletpath.arg=<\u8DEF\u5F84>
+main.opt.docletpath.desc=\u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+
+main.opt.module.source.path.arg=<\u8DEF\u5F84>
+main.opt.module.source.path.desc=\u6307\u5B9A\u67E5\u627E\u591A\u4E2A\u6A21\u5757\u7684\u8F93\u5165\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E
+
+main.opt.upgrade.module.path.arg=<\u8DEF\u5F84>
+main.opt.upgrade.module.path.desc=\u8986\u76D6\u53EF\u5347\u7EA7\u6A21\u5757\u4F4D\u7F6E
+
+main.opt.module.path.arg=<\u8DEF\u5F84>
+main.opt.module.path.desc=\u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E
+
+main.opt.add.modules.arg=<\u6A21\u5757>(,<\u6A21\u5757>)*
+main.opt.add.modules.desc=\u9664\u4E86\u521D\u59CB\u6A21\u5757\u4E4B\u5916\u8981\u89E3\u6790\u7684\u6839\u6A21\u5757; \n\u5982\u679C <\u6A21\u5757> \u4E3A ALL-MODULE-PATH, \n\u5219\u4E3A\u6A21\u5757\u8DEF\u5F84\u4E2D\u7684\u6240\u6709\u6A21\u5757\u3002
+
+main.opt.limit.modules.arg=<\u6A21\u5757>(,<\u6A21\u5757>)*
+main.opt.limit.modules.desc=\u9650\u5236\u53EF\u89C2\u5BDF\u6A21\u5757\u7684\u9886\u57DF
+
+main.opt.source.path.arg=<\u8DEF\u5F84>
+main.opt.source.path.desc=\u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E
+
+main.opt.class.path.arg=<\u8DEF\u5F84>
+main.opt.class.path.desc=\u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+
+main.opt.exclude.arg=<\u7A0B\u5E8F\u5305\u5217\u8868>
+main.opt.exclude.desc=\u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868
 
-main.Xusage.foot=\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002
+main.opt.subpackages.arg=<\u5B50\u7A0B\u5E8F\u5305\u5217\u8868>
+main.opt.subpackages.desc=\u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305
+
+main.opt.breakiterator.desc=\u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5
+
+main.opt.bootclasspath.arg=<\u8DEF\u5F84>
+main.opt.bootclasspath.desc=\u8986\u76D6\u7528\u4E8E\u975E\u6A21\u5757\u5316\u53D1\u884C\u7248\u7684\n\u5E73\u53F0\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+
+main.opt.system.arg=<jdk>
+main.opt.system.desc=\u8986\u76D6\u7528\u4E8E\u6A21\u5757\u5316\u53D1\u884C\u7248\u7684\u7CFB\u7EDF\u6A21\u5757\u7684\u4F4D\u7F6E
+
+main.opt.release.arg=<\u53D1\u884C\u7248>
+main.opt.release.desc=\u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027
+
+main.opt.source.arg=<\u53D1\u884C\u7248>
+main.opt.source.desc=\u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027
+
+main.opt.extdirs.arg=<\u76EE\u5F55\u5217\u8868>
+main.opt.extdirs.desc=\u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E
+
+main.opt.verbose.desc=\u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u6D88\u606F
+
+main.opt.locale.arg=<\u540D\u79F0>
+main.opt.locale.desc=\u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982, en_US \u6216 en_US_WIN
+
+main.opt.encoding.arg=<\u540D\u79F0>
+main.opt.encoding.desc=\u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0
+
+main.opt.quiet.desc=\u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F
 
-main.doclet.usage.header=\u7531 {0} doclet \u63D0\u4F9B:
+main.opt.J.arg=<\u6807\u8BB0>
+main.opt.J.desc=\u76F4\u63A5\u5C06 <\u6807\u8BB0> \u4F20\u9012\u7ED9\u8FD0\u884C\u65F6\u7CFB\u7EDF
+
+main.opt.X.desc=\u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\u5E76\u9000\u51FA
+
+main.usage.foot=\nGNU \u6837\u5F0F\u7684\u9009\u9879\u53EF\u4F7F\u7528 '=' (\u800C\u975E\u7A7A\u767D) \u6765\u5206\u9694\u9009\u9879\u540D\u79F0\n\u53CA\u5176\u503C\u3002\n
+
+main.Xusage=
+
+main.opt.Xmaxerrs.arg=<\u6570\u5B57>
+main.opt.Xmaxerrs.desc=\u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u9519\u8BEF\u7684\u6700\u5927\u6570\u76EE
+
+main.opt.Xmaxwarns.arg=<\u6570\u5B57>
+main.opt.Xmaxwarns.desc=\u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u8B66\u544A\u7684\u6700\u5927\u6570\u76EE
+
+main.opt.add.exports.arg=<\u6A21\u5757>/<\u7A0B\u5E8F\u5305>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*
+main.opt.add.exports.desc=\u6307\u5B9A\u88AB\u89C6\u4E3A\u5DF2\u4ECE\u5176\u5B9A\u4E49\u6A21\u5757\u5BFC\u51FA\u5230\u5176\u4ED6\u6A21\u5757\n\u6216\u8005\u5BFC\u51FA\u5230\u6240\u6709\u672A\u547D\u540D\u6A21\u5757 (\u5982\u679C <\u5176\u4ED6\u6A21\u5757> \n\u4E3A ALL-UNNAMED) \u7684\u7A0B\u5E8F\u5305
+
+main.opt.add.reads.arg=<\u6A21\u5757>=<\u5176\u4ED6\u6A21\u5757>(,<\u5176\u4ED6\u6A21\u5757>)*
+main.opt.add.reads.desc=\u6307\u5B9A\u88AB\u89C6\u4E3A\u7ED9\u5B9A\u6A21\u5757\u9700\u8981\u7684\u5176\u4ED6\u6A21\u5757\u3002\n<\u5176\u4ED6\u6A21\u5757> \u53EF\u4EE5\u4E3A ALL-UNNAMED \n\u4EE5\u4FBF\u8981\u6C42\u672A\u547D\u540D\u6A21\u5757\u3002
+
+main.opt.Xmodule.arg=<\u6A21\u5757\u540D\u79F0>
+main.opt.Xmodule.desc=\u6307\u5B9A\u6B63\u5728\u7F16\u8BD1\u7684\u7C7B\u6240\u5C5E\u7684\u6A21\u5757
+
+main.opt.patch.module.arg=<\u6A21\u5757>=<\u6587\u4EF6>(:<\u6587\u4EF6>)*
+main.opt.patch.module.desc=\u4F7F\u7528\nJAR \u6587\u4EF6\u6216\u76EE\u5F55\u4E2D\u7684\u7C7B\u548C\u8D44\u6E90\u8986\u76D6\n        \u6216\u589E\u5F3A\u6A21\u5757
+
+main.opt.Xold.desc=\u8C03\u7528\u4F20\u7EDF javadoc \u5DE5\u5177
+
+main.Xusage.foot=\n\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002
+
+main.doclet.usage.header=\n\u7531 {0} doclet \u63D0\u4F9B:
 
 main.requires_argument=\u9009\u9879{0}\u9700\u8981\u53C2\u6570\u3002
+main.unnecessary_arg_provided=\u9009\u9879 {0} \u4E0D\u9700\u8981\u53C2\u6570
+main.only_one_argument_with_equals=\u4E0D\u80FD\u5C06 ''='' \u8BED\u6CD5\u7528\u4E8E\u9700\u8981\u591A\u4E2A\u53C2\u6570\u7684\u9009\u9879
 main.invalid_flag=\u65E0\u6548\u7684\u6807\u8BB0: {0}
-main.No_packages_or_classes_specified=\u672A\u6307\u5B9A\u7A0B\u5E8F\u5305\u6216\u7C7B\u3002
-main.incompatible.access.flags=\u6307\u5B9A\u4E86\u591A\u4E2A -public, -private, -package \u6216 -protected\u3002
+main.No_modules_packages_or_classes_specified=\u672A\u6307\u5B9A\u6A21\u5757, \u7A0B\u5E8F\u5305\u6216\u7C7B\u3002
+main.module_not_found=\u672A\u627E\u5230\u6A21\u5757 {0}\u3002\n
 main.cant.read=\u65E0\u6CD5\u8BFB\u53D6{0}
 main.Loading_source_files_for_package=\u6B63\u5728\u52A0\u8F7D\u7A0B\u5E8F\u5305{0}\u7684\u6E90\u6587\u4EF6...
 main.Loading_source_file=\u6B63\u5728\u52A0\u8F7D\u6E90\u6587\u4EF6{0}...
 main.Building_tree=\u6B63\u5728\u6784\u9020 Javadoc \u4FE1\u606F...
 main.no_source_files_for_package=\u6CA1\u6709\u7A0B\u5E8F\u5305{0}\u7684\u6E90\u6587\u4EF6
-main.fatal.error=\u81F4\u547D\u9519\u8BEF
-main.fatal.exception=\u81F4\u547D\u5F02\u5E38\u9519\u8BEF
+main.package_not_found=\u627E\u4E0D\u5230\u5305{0}
+main.fatal.error=\u9047\u5230\u81F4\u547D\u9519\u8BEF: {0}
 main.out.of.memory=java.lang.OutOfMemoryError: \u8BF7\u589E\u5927\u5185\u5B58\u3002\n\u4F8B\u5982, \u5BF9\u4E8E JDK \u7ECF\u5178\u6216 HotSpot VM, \u8BF7\u589E\u5927\u9009\u9879 -J-Xmx,\n\u4F8B\u5982 -J-Xmx32m\u3002
 main.done_in=[\u5728 {0} \u6BEB\u79D2\u5185\u5B8C\u6210]
 main.more_than_one_doclet_specified_0_and_1=\u6307\u5B9A\u4E86\u591A\u4E2A doclet ({0}\u548C{1})\u3002
+main.doclet_could_not_get_location=\u65E0\u6CD5\u83B7\u53D6 {0} \u7684\u4F4D\u7F6E
 main.doclet_could_not_set_location=\u65E0\u6CD5\u8BBE\u7F6E {0} \u7684\u4F4D\u7F6E
 main.doclet_no_classloader_found=\u65E0\u6CD5\u83B7\u53D6\u7C7B\u52A0\u8F7D\u5668\u6765\u52A0\u8F7D {0}
 main.could_not_instantiate_class=\u65E0\u6CD5\u5B9E\u4F8B\u5316\u7C7B {0}
 main.doclet_class_not_found=\u627E\u4E0D\u5230 doclet \u7C7B{0}
-main.illegal_locale_name=\u8BED\u8A00\u73AF\u5883\u4E0D\u53EF\u7528: {0}
-main.malformed_locale_name=\u683C\u5F0F\u9519\u8BEF\u7684\u8BED\u8A00\u73AF\u5883\u540D\u79F0: {0}
+main.illegal_locale_name=\u533A\u57DF\u8BBE\u7F6E\u4E0D\u53EF\u7528: {0}
+main.malformed_locale_name=\u683C\u5F0F\u9519\u8BEF\u7684\u533A\u57DF\u8BBE\u7F6E\u540D\u79F0: {0}
 main.file_not_found=\u627E\u4E0D\u5230\u6587\u4EF6: "{0}"
 main.file_ignored=\u5DF2\u5FFD\u7565\u6587\u4EF6: "{0}" (\u5C1A\u4E0D\u652F\u6301)
 main.illegal_class_name=\u975E\u6CD5\u7C7B\u540D: "{0}"
 main.illegal_package_name=\u975E\u6CD5\u7684\u7A0B\u5E8F\u5305\u540D\u79F0: "{0}"
+main.illegal_option_value=\u975E\u6CD5\u9009\u9879\u503C: "{0}"
 main.release.bootclasspath.conflict=\u9009\u9879{0}\u65E0\u6CD5\u4E0E -release \u4E00\u8D77\u4F7F\u7528
 main.unsupported.release.version=\u4E0D\u652F\u6301\u53D1\u884C\u7248\u672C {0}
 main.release.not.standard.file.manager=\u6307\u5B9A\u4E86 -release \u9009\u9879, \u4F46\u63D0\u4F9B\u7684 JavaFileManager \u4E0D\u662F StandardJavaFileManager\u3002
+main.file.manager.list=\u5217\u51FA\u6587\u4EF6\u65F6 FileManager \u51FA\u9519: "{0}"
+main.assertion.error=\u65AD\u8A00\u5931\u8D25: "{0}}"
 main.unknown.error=\u51FA\u73B0\u672A\u77E5\u9519\u8BEF
+main.internal.error=\u51FA\u73B0\u5185\u90E8\u9519\u8BEF
+main.unexpected.exception=\u6355\u83B7\u5230\u610F\u5916\u7684\u5F02\u5E38\u9519\u8BEF: {0}
+doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002
 main.legacy_api=\u5DF2\u8BA1\u5212\u5728\u672A\u6765\u7684 JDK \u53D1\u884C\u7248\u4E2D\u5220\u9664\u7A0B\u5E8F\u5305\ncom.sun.javadoc, com.sun.tools.doclets\n\u53CA\u5176\u5B9E\u73B0\u4E2D\u7684\u65E7 Doclet \u548C Taglet API\u3002\n\u8FD9\u4E9B\u7EC4\u4EF6\u5728 jdk.javadoc.doclet \u4E2D\u5DF2\u7531\u65B0 API \u53D6\u4EE3\u3002\n\u5F3A\u70C8\u5EFA\u8BAE\u7528\u6237\u79FB\u690D\u5230\u65B0 API\u3002\n
 
 javadoc.class_not_found=\u627E\u4E0D\u5230\u7C7B{0}\u3002
--- a/langtools/src/jdk.javadoc/share/classes/module-info.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/module-info.java	Tue Dec 13 02:04:23 2016 +0100
@@ -46,5 +46,8 @@
 
     provides javax.tools.DocumentationTool
         with jdk.javadoc.internal.api.JavadocTool;
+
+    provides javax.tools.Tool
+        with jdk.javadoc.internal.api.JavadocTool;
 }
 
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -34,41 +34,44 @@
 main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059:
 
 
-main.opt.help=\  -help  --help  -?        \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B
+main.opt.help=\  -help  --help  -?                \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B
 
-main.opt.version=\  -version                 \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
+main.opt.version=\  -version                         \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
 
-main.opt.v=\  -v  -verbose             \u8FFD\u52A0\u60C5\u5831\u3092\u51FA\u529B\u3059\u308B
+main.opt.v=\  -v  -verbose                     \u8FFD\u52A0\u60C5\u5831\u3092\u51FA\u529B\u3059\u308B
 
-main.opt.l=\  -l                       \u884C\u756A\u53F7\u3068\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u8868\u3092\u51FA\u529B\u3059\u308B
+main.opt.l=\  -l                               \u884C\u756A\u53F7\u3068\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u8868\u3092\u51FA\u529B\u3059\u308B
+
+main.opt.public=\  -public                          public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B
 
-main.opt.public=\  -public                  public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B
+main.opt.protected=\  -protected                       protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B
 
-main.opt.protected=\  -protected               protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B
+main.opt.package=\  -package                         package/protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\n                                   \u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)
 
-main.opt.package=\  -package                 package/protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\n                           \u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)
+main.opt.p=\  -p  -private                     \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u8868\u793A\u3059\u308B
 
-main.opt.p=\  -p  -private             \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u8868\u793A\u3059\u308B
+main.opt.c=\  -c                               \u30B3\u30FC\u30C9\u3092\u9006\u30A2\u30BB\u30F3\u30D6\u30EB\u3059\u308B
 
-main.opt.c=\  -c                       \u30B3\u30FC\u30C9\u3092\u9006\u30A2\u30BB\u30F3\u30D6\u30EB\u3059\u308B
+main.opt.s=\  -s                               \u5185\u90E8\u30BF\u30A4\u30D7\u7F72\u540D\u3092\u51FA\u529B\u3059\u308B
 
-main.opt.s=\  -s                       \u5185\u90E8\u30BF\u30A4\u30D7\u7F72\u540D\u3092\u51FA\u529B\u3059\u308B
+main.opt.class_path=\  --class-path <path>              \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
 
-main.opt.classpath=\  -classpath <path>        \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+main.opt.classpath=\  -classpath <path>                \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
 
-main.opt.cp=\  -cp <path>               \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+main.opt.cp=\  -cp <path>                       \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
 
-main.opt.bootclasspath=\  -bootclasspath <path>    \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
+main.opt.bootclasspath=\  -bootclasspath <path>            \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
 
-main.opt.upgrademodulepath=\  -upgrademodulepath <path>    \u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+main.opt.upgrade_module_path=\  --upgrade-module-path <path>     \u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
 
-main.opt.system=\  -system <jdk>            \u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+main.opt.system=\  --system <jdk>                   \u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
 
-main.opt.modulepath=\  -modulepath <path>       \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+main.opt.module_path=\  --module-path <path>             \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B
+
+main.opt.constants=\  -constants                       final\u5B9A\u6570\u3092\u8868\u793A\u3059\u308B
 
-main.opt.constants=\  -constants               final\u5B9A\u6570\u3092\u8868\u793A\u3059\u308B
-
+main.opt.sysinfo=\  -sysinfo                         \u51E6\u7406\u3057\u3066\u3044\u308B\u30AF\u30E9\u30B9\u306E\u30B7\u30B9\u30C6\u30E0\u60C5\u5831(\u30D1\u30B9\u3001\u30B5\u30A4\u30BA\u3001\u65E5\u4ED8\u3001MD5\u30CF\u30C3\u30B7\u30E5)\n                                   \u3092\u8868\u793A\u3059\u308B
 
-main.opt.sysinfo=\  -sysinfo                 \u51E6\u7406\u3057\u3066\u3044\u308B\u30AF\u30E9\u30B9\u306E\u30B7\u30B9\u30C6\u30E0\u60C5\u5831(\u30D1\u30B9\u3001\u30B5\u30A4\u30BA\u3001\u65E5\u4ED8\u3001MD5\u30CF\u30C3\u30B7\u30E5)\n                           \u3092\u8868\u793A\u3059\u308B
+main.opt.module=\  --module <module>\u3001-m <module>   \u9006\u30A2\u30BB\u30F3\u30D6\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u3092\u542B\u3080\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3059\u308B
 
-main.opt.m=\  -m <module-name>         \u9006\u30A2\u30BB\u30F3\u30D6\u30EB\u3055\u308C\u308B\u30AF\u30E9\u30B9\u3092\u542B\u3080\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3059\u308B
+main.usage.foot=\nGNU\u30B9\u30BF\u30A4\u30EB\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u306F\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u540D\u524D\u3068\u305D\u306E\u5024\u3092\u533A\u5207\u308B\u305F\u3081\u306B\u7A7A\u767D\u3067\u306F\u306A\u304F'='\u3092\n\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n\n\u8868\u793A\u3055\u308C\u308B\u5404\u30AF\u30E9\u30B9\u306F\u3001\u30D5\u30A1\u30A4\u30EB\u540D\u3001URL\u307E\u305F\u306F\u305D\u306E\u5B8C\u5168\u4FEE\u98FE\u30AF\u30E9\u30B9\u540D\n\u3067\u6307\u5B9A\u3067\u304D\u307E\u3059\u3002\u4F8B:\n   path/to/MyClass.class\n   jar:file:///path/to/MyJar.jar!/mypkg/MyClass.class\n   java.lang.Object\n
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -34,41 +34,44 @@
 main.usage=\u7528\u6CD5: {0} <options> <classes>\n\u5176\u4E2D, \u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
 
 
-main.opt.help=\  -help  --help  -?        \u8F93\u51FA\u6B64\u7528\u6CD5\u6D88\u606F
+main.opt.help=\  -help  --help  -?                \u8F93\u51FA\u6B64\u7528\u6CD5\u6D88\u606F
 
-main.opt.version=\  -version                 \u7248\u672C\u4FE1\u606F
+main.opt.version=\  -version                         \u7248\u672C\u4FE1\u606F
 
-main.opt.v=\  -v  -verbose             \u8F93\u51FA\u9644\u52A0\u4FE1\u606F
+main.opt.v=\  -v  -verbose                     \u8F93\u51FA\u9644\u52A0\u4FE1\u606F
 
-main.opt.l=\  -l                       \u8F93\u51FA\u884C\u53F7\u548C\u672C\u5730\u53D8\u91CF\u8868
+main.opt.l=\  -l                               \u8F93\u51FA\u884C\u53F7\u548C\u672C\u5730\u53D8\u91CF\u8868
+
+main.opt.public=\  -public                          \u4EC5\u663E\u793A\u516C\u5171\u7C7B\u548C\u6210\u5458
 
-main.opt.public=\  -public                  \u4EC5\u663E\u793A\u516C\u5171\u7C7B\u548C\u6210\u5458
+main.opt.protected=\  -protected                       \u663E\u793A\u53D7\u4FDD\u62A4\u7684/\u516C\u5171\u7C7B\u548C\u6210\u5458
 
-main.opt.protected=\  -protected               \u663E\u793A\u53D7\u4FDD\u62A4\u7684/\u516C\u5171\u7C7B\u548C\u6210\u5458
+main.opt.package=\  -package                         \u663E\u793A\u7A0B\u5E8F\u5305/\u53D7\u4FDD\u62A4\u7684/\u516C\u5171\u7C7B\n                                   \u548C\u6210\u5458 (\u9ED8\u8BA4)
 
-main.opt.package=\  -package                 \u663E\u793A\u7A0B\u5E8F\u5305/\u53D7\u4FDD\u62A4\u7684/\u516C\u5171\u7C7B\n                           \u548C\u6210\u5458 (\u9ED8\u8BA4)
+main.opt.p=\  -p  -private                     \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458
 
-main.opt.p=\  -p  -private             \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458
+main.opt.c=\  -c                               \u5BF9\u4EE3\u7801\u8FDB\u884C\u53CD\u6C47\u7F16
 
-main.opt.c=\  -c                       \u5BF9\u4EE3\u7801\u8FDB\u884C\u53CD\u6C47\u7F16
+main.opt.s=\  -s                               \u8F93\u51FA\u5185\u90E8\u7C7B\u578B\u7B7E\u540D
 
-main.opt.s=\  -s                       \u8F93\u51FA\u5185\u90E8\u7C7B\u578B\u7B7E\u540D
+main.opt.class_path=\  --class-path <\u8DEF\u5F84>              \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
 
-main.opt.classpath=\  -classpath <path>        \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+main.opt.classpath=\  -classpath <\u8DEF\u5F84>                \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
 
-main.opt.cp=\  -cp <path>               \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+main.opt.cp=\  -cp <\u8DEF\u5F84>                       \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
 
-main.opt.bootclasspath=\  -bootclasspath <path>    \u8986\u76D6\u5F15\u5BFC\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+main.opt.bootclasspath=\  -bootclasspath <\u8DEF\u5F84>            \u8986\u76D6\u5F15\u5BFC\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
 
-main.opt.upgrademodulepath=\  -upgrademodulepath <path>    \u6307\u5B9A\u67E5\u627E\u53EF\u5347\u7EA7\u6A21\u5757\u7684\u4F4D\u7F6E
+main.opt.upgrade_module_path=\  --upgrade-module-path <\u8DEF\u5F84>     \u6307\u5B9A\u67E5\u627E\u53EF\u5347\u7EA7\u6A21\u5757\u7684\u4F4D\u7F6E
 
-main.opt.system=\  -system <jdk>            \u6307\u5B9A\u67E5\u627E\u7CFB\u7EDF\u6A21\u5757\u7684\u4F4D\u7F6E
+main.opt.system=\  --system <jdk>                   \u6307\u5B9A\u67E5\u627E\u7CFB\u7EDF\u6A21\u5757\u7684\u4F4D\u7F6E
 
-main.opt.modulepath=\  -modulepath <path>       \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E
+main.opt.module_path=\  --module-path <\u8DEF\u5F84>             \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E
+
+main.opt.constants=\  -constants                       \u663E\u793A\u6700\u7EC8\u5E38\u91CF
 
-main.opt.constants=\  -constants               \u663E\u793A\u6700\u7EC8\u5E38\u91CF
-
+main.opt.sysinfo=\  -sysinfo                         \u663E\u793A\u6B63\u5728\u5904\u7406\u7684\u7C7B\u7684\n                                   \u7CFB\u7EDF\u4FE1\u606F (\u8DEF\u5F84, \u5927\u5C0F, \u65E5\u671F, MD5 \u6563\u5217)
 
-main.opt.sysinfo=\  -sysinfo                 \u663E\u793A\u6B63\u5728\u5904\u7406\u7684\u7C7B\u7684\n                           \u7CFB\u7EDF\u4FE1\u606F (\u8DEF\u5F84, \u5927\u5C0F, \u65E5\u671F, MD5 \u6563\u5217)
+main.opt.module=\  --module <\u6A21\u5757>, -m <\u6A21\u5757>       \u6307\u5B9A\u5305\u542B\u8981\u53CD\u6C47\u7F16\u7684\u7C7B\u7684\u6A21\u5757
 
-main.opt.m=\  -m <module-name>         \u6307\u5B9A\u5305\u542B\u8981\u53CD\u6C47\u7F16\u7684\u7C7B\u7684\u6A21\u5757
+main.usage.foot=\nGNU \u6837\u5F0F\u7684\u9009\u9879\u53EF\u4F7F\u7528 '=' (\u800C\u975E\u7A7A\u767D) \u6765\u5206\u9694\u9009\u9879\u540D\u79F0\n\u53CA\u5176\u503C\u3002\n\n\u6BCF\u4E2A\u7C7B\u53EF\u7531\u5176\u6587\u4EF6\u540D, URL \u6216\u5176\n\u5168\u9650\u5B9A\u7C7B\u540D\u6307\u5B9A\u3002\u793A\u4F8B:\n   path/to/MyClass.class\n   jar:file:///path/to/MyJar.jar!/mypkg/MyClass.class\n   java.lang.Object\n
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,77 +1,84 @@
-main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <path ...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F-help\u3092\u4F7F\u7528\u3057\u307E\u3059
+main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <path ...>]\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u3001-help\u307E\u305F\u306F--help\u3092\u4F7F\u7528\u3057\u307E\u3059
 
 main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <path ...>]\n<path>\u306B\u306F\u3001.class\u30D5\u30A1\u30A4\u30EB\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001JAR\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u540D\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\u3002\n\n\u4F7F\u7528\u3067\u304D\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:
 
 error.prefix=\u30A8\u30E9\u30FC:
 warn.prefix=\u8B66\u544A:
 
-main.opt.h=\  -h -?        -help                \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3057\u307E\u3059
+main.opt.h=\  -h -? -help\n  --help                        \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3057\u307E\u3059
 
-main.opt.version=\  -version                          \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
+main.opt.version=\  -version --version            \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
 
-main.opt.v=\  -v           -verbose             \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n                                     -verbose:class -filter:none\u3068\u540C\u7B49\u3067\u3059\u3002\n  -verbose:package                  \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                     (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n  -verbose:class                    \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                     (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)
+main.opt.v=\  -v       -verbose             \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n                                -verbose:class -filter:none\u3068\u540C\u7B49\u3067\u3059\u3002\n  -verbose:package              \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                 (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n  -verbose:class                \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)
 
-main.opt.s=\  -s           -summary             \u4F9D\u5B58\u6027\u306E\u30B5\u30DE\u30EA\u30FC\u306E\u307F\u51FA\u529B\u3057\u307E\u3059
+main.opt.s=\  -s       -summary             \u4F9D\u5B58\u6027\u306E\u30B5\u30DE\u30EA\u30FC\u306E\u307F\u51FA\u529B\u3057\u307E\u3059
 
-main.opt.f=\  -f <regex>   -filter <regex>       \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\n                                     \u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\u3002\u8907\u6570\u56DE\u6307\u5B9A\u3055\u308C\u305F\u5834\u5408\u3001\u6700\u5F8C\u306E\u3082\u306E\u304C\n                                    \u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n  -filter:package                    \u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\u3002\n                                    \u3053\u308C\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u3059\u3002\n  -filter:archive                    \u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n  -filter:module                       \u540C\u3058\u30E2\u30B8\u30E5\u30FC\u30EB\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n  -filter:none                       -filter:package\u304A\u3088\u3073-filter:archive\u306E\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u306F\n                                    \u884C\u308F\u308C\u307E\u305B\u3093\u3002-filter\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u304C\n                                    \u5F15\u304D\u7D9A\u304D\u9069\u7528\u3055\u308C\u307E\u3059\u3002\n
-main.opt.p=\n\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3:\n  -p <pkgname> -package <pkgname>    \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                     (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)\u3002
+main.opt.f=\  -f <regex>   -filter <regex>    \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\n                                     \u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\u3002\u8907\u6570\u56DE\u6307\u5B9A\u3055\u308C\u305F\u5834\u5408\u3001\u6700\u5F8C\u306E\u3082\u306E\u304C\n                                    \u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n  -filter:package                    \u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\u3002\n                                    \u3053\u308C\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u3059\u3002\n  -filter:archive                    \u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n  -filter:module                       \u540C\u3058\u30E2\u30B8\u30E5\u30FC\u30EB\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n  -filter:none                       -filter:package\u304A\u3088\u3073-filter:archive\u306E\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u306F\n                                    \u884C\u308F\u308C\u307E\u305B\u3093\u3002-filter\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u304C\n                                    \u5F15\u304D\u7D9A\u304D\u9069\u7528\u3055\u308C\u307E\u3059\u3002\n
+main.opt.p=\n\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3:\n  -p <pkg>\n  -package <pkg>\n  --package <pkg>               \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)\u3002
 
-main.opt.e=\  -e <regex> -regex <regex>         \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\u3002
+main.opt.e=\  -e <regex>\n  -regex <regex>\n  --regex <regex>               \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\u3002
 
-main.opt.requires=\  -requires <module-name>           \u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                    (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)\u3002\n                                    -package\u3001-regex\u3001-requires\u306F\u76F8\u4E92\u306B\u6392\u4ED6\u7684\u3067\u3059\u3002
+main.opt.require=\  --require <module-name>       \u6307\u5B9A\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                 (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)\u3002--package\u3001\n                                --regex\u3001--require\u306F\u76F8\u4E92\u306B\u6392\u4ED6\u7684\u3067\u3059\u3002
 
-main.opt.include=\n\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u3092\u30D5\u30A3\u30EB\u30BF\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3:\n  -include <regex>                  \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30AF\u30E9\u30B9\u306B\u5206\u6790\u3092\u5236\u9650\u3057\u307E\u3059\n                                     \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u306E\n                                     \u30EA\u30B9\u30C8\u304C\u30D5\u30A3\u30EB\u30BF\u3055\u308C\u307E\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u3092\u4F9D\u5B58\u6027\u306B\n                                     \u9069\u7528\u3059\u308B-p\u304A\u3088\u3073-e\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059
+main.opt.include=\n\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u3092\u30D5\u30A3\u30EB\u30BF\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3:\n  -include <regex>              \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30AF\u30E9\u30B9\u306B\u5206\u6790\u3092\u5236\u9650\u3057\u307E\u3059\n                                     \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u306E\n                                     \u30EA\u30B9\u30C8\u304C\u30D5\u30A3\u30EB\u30BF\u3055\u308C\u307E\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u3092\u4F9D\u5B58\u6027\u306B\n                                     \u9069\u7528\u3059\u308B-p\u304A\u3088\u3073-e\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059
 
-main.opt.P=\  -P           -profile             \u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u542B\u3080\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u8868\u793A\u3057\u307E\u3059
+main.opt.P=\  -P       -profile             \u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u542B\u3080\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u8868\u793A\u3057\u307E\u3059
 
-main.opt.cp=\  -cp <path>   -classpath <path>    \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059
+main.opt.cp=\  -cp <path>\n  -classpath <path>\n  --class-path <path>           \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.mp=\  -mp <module path>...\n  -modulepath <module path>...      \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u307E\u3059
+main.opt.module-path=\  --module-path <module path>   \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.upgrademodulepath=\  -upgrademodulepath <module path>...  \u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u307E\u3059
+main.opt.upgrade-module-path=\  --upgrade-module-path <module path>  \u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.system=\  -system <java-home>               \u4EE3\u66FF\u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u307E\u3059
+main.opt.system=\  --system <java-home>          \u4EE3\u66FF\u30B7\u30B9\u30C6\u30E0\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.addmods=\  -addmods <module-name>[,<module-name>...]\n                                    \u5206\u6790\u7528\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30EB\u30FC\u30C8\u30FB\u30BB\u30C3\u30C8\u306B\u8FFD\u52A0\u3057\u307E\u3059
+main.opt.add-modules=\  --add-modules <module-name>[,<module-name>...]\n                                \u5206\u6790\u7528\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30EB\u30FC\u30C8\u30FB\u30BB\u30C3\u30C8\u306B\u8FFD\u52A0\u3057\u307E\u3059
 
-main.opt.m=\  -m <module-name>                  \u5206\u6790\u7528\u306B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059
+main.opt.m=\  -m <module-name>\n  --module <module-name>        \u5206\u6790\u7528\u306B\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.R=\  -R           -recursive            \u3059\u3079\u3066\u306E\u30E9\u30F3\u30BF\u30A4\u30E0\u4F9D\u5B58\u6027\u3092\u518D\u5E30\u7684\u306B\u30C8\u30E9\u30D0\u30FC\u30B9\u3057\u307E\u3059\u3002\n                                     -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-filter:none\u3092\u610F\u5473\u3057\u307E\u3059\u3002-p\u3001-e\u3001-f\n                                     \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u306E\u307F\n                                     \u5206\u6790\u3055\u308C\u307E\u3059\u3002
+main.opt.R=\  -R       -recursive           \u3059\u3079\u3066\u306E\u30E9\u30F3\u30BF\u30A4\u30E0\u4F9D\u5B58\u6027\u3092\u518D\u5E30\u7684\u306B\u30C8\u30E9\u30D0\u30FC\u30B9\u3057\u307E\u3059\u3002\n                                -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-filter:none\u3092\u610F\u5473\u3057\u307E\u3059\u3002-p\u3001-e\u3001-f\n                                \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u306E\u307F\n                                 \u5206\u6790\u3055\u308C\u307E\u3059\u3002
 
-main.opt.I=\  -I           -inverse             \u4ED6\u306E\u6307\u5B9A\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3054\u3068\u306B\u4F9D\u5B58\u6027\u3092\u5206\u6790\u3057\u3001\n                                    \u4E00\u81F4\u3059\u308B\u30CE\u30FC\u30C9\u306B\u76F4\u63A5\u304A\u3088\u3073\u9593\u63A5\u7684\u306B\u4F9D\u5B58\u3059\u308B\n                                    \u3059\u3079\u3066\u306E\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u3092\u691C\u51FA\u3057\u307E\u3059\u3002\n                                    \u3053\u308C\u306F\u3001\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u8868\u793A\u5206\u6790\n                                    \u304A\u3088\u3073\u51FA\u529B\u4F9D\u5B58\u6027\u30B5\u30DE\u30EA\u30FC\u306E\u9006\u306B\u76F8\u5F53\u3057\u307E\u3059\u3002\n                                    \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-requires\u3001-package\u307E\u305F\u306F-regex\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\n                                    \u4E00\u7DD2\u306B\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
+main.opt.I=\  -I       --inverse            \u4ED6\u306E\u6307\u5B9A\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3054\u3068\u306B\u4F9D\u5B58\u6027\u3092\u5206\u6790\u3057\u3001\n                                \u4E00\u81F4\u3059\u308B\u30CE\u30FC\u30C9\u306B\u76F4\u63A5\u304A\u3088\u3073\u9593\u63A5\u7684\u306B\u4F9D\u5B58\u3059\u308B\n                                \u3059\u3079\u3066\u306E\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u3092\u691C\u51FA\u3057\u307E\u3059\u3002\n                                \u3053\u308C\u306F\u3001\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u8868\u793A\u5206\u6790\n                                \u304A\u3088\u3073\u51FA\u529B\u4F9D\u5B58\u6027\u30B5\u30DE\u30EA\u30FC\u306E\u9006\u306B\u76F8\u5F53\u3057\u307E\u3059\u3002\n                                \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F--require\u3001--package\u307E\u305F\u306F--regex\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\n                                \u4E00\u7DD2\u306B\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
 
-main.opt.ct=\  -ct          -compile-time        \u63A8\u79FB\u7684\u306A\u4F9D\u5B58\u6027\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u8868\u793A\n                                    \u4F8B: -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u8868\u793A\u3002\n                                    \u4ED6\u306E\u6307\u5B9A\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3054\u3068\u306B\u4F9D\u5B58\u6027\u3092\u5206\u6790\u3057\u307E\u3059\n                                    \u4F9D\u5B58\u6027\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\n                                    \u691C\u51FA\u3055\u308C\u305F\u5834\u5408\u3001\u305D\u306E\u5305\u542B\u3059\u308B\u30A2\u30FC\u30AB\u30A4\u30D6\u306E\n                                    \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u5206\u6790\u3055\u308C\u307E\u3059\u3002
+main.opt.compile-time=\  --compile-time                \u63A8\u79FB\u7684\u306A\u4F9D\u5B58\u6027\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u8868\u793A\n                                \u4F8B: -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u6642\u306E\u8868\u793A\u3002\n                                \u4ED6\u306E\u6307\u5B9A\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3054\u3068\u306B\u4F9D\u5B58\u6027\u3092\u5206\u6790\u3057\u307E\u3059\n                                \u4F9D\u5B58\u6027\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u3089\n                                \u691C\u51FA\u3055\u308C\u305F\u5834\u5408\u3001\u305D\u306E\u5305\u542B\u3059\u308B\u30A2\u30FC\u30AB\u30A4\u30D6\u306E\n                                \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u304C\u5206\u6790\u3055\u308C\u307E\u3059\u3002
 
-main.opt.apionly=\  -apionly                          \u5206\u6790\u3092API\u3001\u3064\u307E\u308A\u3001\u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30AF\u30E9\u30B9\u306E\n                                     \u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30E1\u30F3\u30D0\u30FC\u304A\u3088\u3073\u4FDD\u8B77\u3055\u308C\u305F\u30E1\u30F3\u30D0\u30FC\u306E\n                                     \u7F72\u540D\u306B\u304A\u3051\u308B\u4F9D\u5B58\u6027(\u30D5\u30A3\u30FC\u30EB\u30C9\u30FB\u30BF\u30A4\u30D7\u3001\u30E1\u30BD\u30C3\u30C9\u30FB\n                                     \u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\u3001\u623B\u3055\u308C\u305F\u30BF\u30A4\u30D7\u3001\u30C1\u30A7\u30C3\u30AF\u3055\u308C\u305F\n                                     \u4F8B\u5916\u30BF\u30A4\u30D7\u306A\u3069)\u306B\u5236\u9650\u3057\u307E\u3059
+main.opt.apionly=\  -apionly\n  --api-only                    \u5206\u6790\u3092API\u3001\u3064\u307E\u308A\u3001\u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30AF\u30E9\u30B9\u306E\n                                \u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30E1\u30F3\u30D0\u30FC\u304A\u3088\u3073\u4FDD\u8B77\u3055\u308C\u305F\u30E1\u30F3\u30D0\u30FC\u306E\n                                \u7F72\u540D\u306B\u304A\u3051\u308B\u4F9D\u5B58\u6027(\u30D5\u30A3\u30FC\u30EB\u30C9\u30FB\u30BF\u30A4\u30D7\u3001\u30E1\u30BD\u30C3\u30C9\u30FB\n                                \u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\u3001\u623B\u3055\u308C\u305F\u30BF\u30A4\u30D7\u3001\u30C1\u30A7\u30C3\u30AF\u3055\u308C\u305F\n                                \u4F8B\u5916\u30BF\u30A4\u30D7\u306A\u3069)\u306B\u5236\u9650\u3057\u307E\u3059\u3002
 
-main.opt.genmoduleinfo=\  -genmoduleinfo <dir>              \u6307\u5B9A\u3057\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Bmodule-info.java\u3092\u751F\u6210\u3057\u307E\u3059\u3002\n                                    \u6307\u5B9A\u3057\u305FJAR\u30D5\u30A1\u30A4\u30EB\u3092\u5206\u6790\u3057\u307E\u3059\u3002\n                                    \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-dotoutput\u307E\u305F\u306F-cp\u3068\u4E00\u7DD2\u306B\n                                    \u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002
+main.opt.generate-module-info=\  --generate-module-info <dir>  \u6307\u5B9A\u3057\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Bmodule-info.java\u3092\u751F\u6210\u3057\u307E\u3059\u3002\n                                \u6307\u5B9A\u3057\u305FJAR\u30D5\u30A1\u30A4\u30EB\u3092\u5206\u6790\u3057\u307E\u3059\u3002\n                                \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F--dot-output\u307E\u305F\u306F--class-path\n                                \u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002
 
-main.opt.check=\  -check <module-name>[,<module-name>...\n                                    \u6307\u5B9A\u3057\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u5206\u6790\u3057\u307E\u3059\n                                    \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u3001\u5206\u6790\u5F8C\u306E\u7D50\u679C\u30E2\u30B8\u30E5\u30FC\u30EB\u4F9D\u5B58\u6027\n                                    \u304A\u3088\u3073\u9077\u79FB\u524A\u6E1B\u5F8C\u306E\u30B0\u30E9\u30D5\u3092\n                                    \u51FA\u529B\u3057\u307E\u3059\u3002\n                                    \u672A\u4F7F\u7528\u306E\u4FEE\u98FE\u3055\u308C\u305F\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3082\u8B58\u5225\u3057\u307E\u3059\u3002
+main.opt.check=\  --check <module-name>[,<module-name>...\n                                \u6307\u5B9A\u3057\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u5206\u6790\u3057\u307E\u3059\n                                \u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u3001\u5206\u6790\u5F8C\u306E\u7D50\u679C\u30E2\u30B8\u30E5\u30FC\u30EB\u4F9D\u5B58\u6027\n                                \u304A\u3088\u3073\u9077\u79FB\u524A\u6E1B\u5F8C\u306E\u30B0\u30E9\u30D5\u3092\n                                \u51FA\u529B\u3057\u307E\u3059\u3002\n                                \u672A\u4F7F\u7528\u306E\u4FEE\u98FE\u3055\u308C\u305F\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3082\u8B58\u5225\u3057\u307E\u3059\u3002
 
 
-main.opt.dotoutput=\  -dotoutput <dir>                  DOT\u30D5\u30A1\u30A4\u30EB\u51FA\u529B\u306E\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
+main.opt.dotoutput=\  -dotoutput <dir>\n  --dot-output <dir>            DOT\u30D5\u30A1\u30A4\u30EB\u51FA\u529B\u306E\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
 
-main.opt.jdkinternals=\  -jdkinternals                     JDK\u5185\u90E8API\u306E\u30AF\u30E9\u30B9\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\u3002\n                                    \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001-include\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3057\u306A\u3044\u3068\u3001\n                                     -classpath\u306E\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u5206\u6790\u3057\u307E\u3059\u3002\n                                     \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-p\u3001-e\u304A\u3088\u3073-s\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u4E00\u7DD2\u306B\n                                    \u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\n                                     \u8B66\u544A: JDK\u5185\u90E8API\u306F\u3001\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u306A\u304F\u306A\u308A\u307E\u3059\u3002
+main.opt.jdkinternals=\  -jdkinternals\n  --jdk-internals               JDK\u5185\u90E8API\u306E\u30AF\u30E9\u30B9\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\u3002\n                                \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001-include\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3057\u306A\u3044\u3068\u3001\n                                --class-path\u306E\u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u5206\u6790\u3057\u307E\u3059\u3002\n                                \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-p\u3001-e\u304A\u3088\u3073-s\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u4E00\u7DD2\u306B\n                                \u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\n                                \u8B66\u544A: JDK\u5185\u90E8API\u306F\u3001\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u306A\u304F\u306A\u308A\u307E\u3059\u3002
 
-main.opt.depth=\  -depth=<depth>                    \u63A8\u79FB\u7684\u306A\u4F9D\u5B58\u6027\u5206\u6790\u306E\u6DF1\u3055\u3092\n                                    \u6307\u5B9A\u3057\u307E\u3059
+main.opt.depth=\  -depth=<depth>                \u63A8\u79FB\u7684\u306A\u4F9D\u5B58\u6027\u5206\u6790\u306E\u6DF1\u3055\u3092\n                                \u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.q=\  -q           -quiet               -genmoduleinfo\u51FA\u529B\u3067\u6B20\u843D\u3057\u3066\u3044\u308B\u4F9D\u5B58\u6027\u3092\u8868\u793A\u3057\u307E\u305B\u3093\u3002
+main.opt.q=\  -q       -quiet               --generate-module-info\u51FA\u529B\u3067\n                                 \u6B20\u843D\u3057\u3066\u3044\u308B\u4F9D\u5B58\u6027\u3092\u8868\u793A\u3057\u307E\u305B\u3093\u3002
+
+main.opt.multi-release=\  --multi-release <version>     \u30DE\u30EB\u30C1\u30EA\u30EA\u30FC\u30B9jar\u30D5\u30A1\u30A4\u30EB\u3092\u51E6\u7406\u3059\u308B\u969B\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\n                                \u6307\u5B9A\u3057\u307E\u3059\u3002<version>\u306F\u30019\u307E\u305F\u306F\u30D9\u30FC\u30B9\u4EE5\u4E0A\u306E\n                                \u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
 
 err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
 err.missing.arg={0}\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
 err.invalid.arg.for.option=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}
 err.option.after.class=\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u30AF\u30E9\u30B9\u306E\u524D\u306B\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
-err.genmoduleinfo.not.jarfile=-genmoduleinfo\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u306F\u3001{0}\u306F\u6709\u52B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093(\u975E\u30E2\u30B8\u30E5\u30E9JAR\u30D5\u30A1\u30A4\u30EB\u306B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059)
+err.genmoduleinfo.not.jarfile={0}\u306F\u3001--generate-module-info\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u3068\u3082\u306B\u6307\u5B9A\u3067\u304D\u306A\u3044\u30E2\u30B8\u30E5\u30E9JAR\u30D5\u30A1\u30A4\u30EB\u3067\u3059
+err.genmoduleinfo.unnamed.package={0}\u306B\u306F\u3001\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u8A31\u53EF\u3055\u308C\u306A\u3044\u540D\u524D\u306E\u306A\u3044\u30D1\u30C3\u30B1\u30FC\u30B8\u304C\u542B\u307E\u308C\u307E\u3059
 err.profiles.msg=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u60C5\u5831\u304C\u3042\u308A\u307E\u305B\u3093
 err.exception.message={0}
 err.invalid.path=\u7121\u52B9\u306A\u30D1\u30B9: {0}
 err.invalid.module.option={0}\u306F{1}\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u4E00\u7DD2\u306B\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002
-err.invalid.filters=-package (-p)\u3001-regex (-e)\u3001-requires\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u3044\u305A\u308C\u304B\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u3059
+err.invalid.filters=--package (-p)\u3001--regex (-e)\u3001--require\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u3044\u305A\u308C\u304B\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u3059
 err.module.not.found=\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}
 err.root.module.not.set=\u30EB\u30FC\u30C8\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30BB\u30C3\u30C8\u304C\u7A7A\u3067\u3059
-err.invalid.inverse.option={0}\u306F-inverse\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
-err.inverse.filter.not.set={0}\u306F-inverse\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
+err.invalid.inverse.option={0}\u306F--inverse\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093
+err.multirelease.option.exists={0}\u306F\u30DE\u30EB\u30C1\u30EA\u30EA\u30FC\u30B9jar\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u304C\u3001--multi-release\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059
+err.multirelease.option.notfound={0}\u306F\u30DE\u30EB\u30C1\u30EA\u30EA\u30FC\u30B9jar\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u304C\u3001--multi-release\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
+err.multirelease.version.associated=\u30AF\u30E9\u30B9{0}\u306F\u3059\u3067\u306B\u30D0\u30FC\u30B8\u30E7\u30F3{1}\u306B\u95A2\u9023\u4ED8\u3051\u3089\u308C\u3066\u3044\u307E\u3059\u3002\u30D0\u30FC\u30B8\u30E7\u30F3{2}\u306E\u8FFD\u52A0\u3092\u8A66\u307F\u307E\u3059
+err.multirelease.jar.malformed=\u4E0D\u6B63\u306A\u30DE\u30EB\u30C1\u30EA\u30EA\u30FC\u30B9jar\u3001{0}\u3001\u4E0D\u6B63\u306A\u30A8\u30F3\u30C8\u30EA: {1}
 warn.invalid.arg=\u30D1\u30B9\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
+warn.skipped.entry={0}
 warn.split.package=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306F{1} {2}\u3067\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059
 warn.replace.useJDKInternals=JDK\u5185\u90E8API\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u304A\u3089\u305A\u3001JDK\u5B9F\u88C5\u5C02\u7528\u3067\u3059\u304C\u3001\u4E92\u63DB\u6027\u306A\u3057\u3067\n\u524A\u9664\u307E\u305F\u306F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u3001\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u4E2D\u65AD\u3055\u305B\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\nJDK\u5185\u90E8API\u306E\u4F9D\u5B58\u6027\u3092\u524A\u9664\u3059\u308B\u3088\u3046\u30B3\u30FC\u30C9\u3092\u5909\u66F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002\nJDK\u5185\u90E8API\u306E\u7F6E\u63DB\u306B\u95A2\u3059\u308B\u6700\u65B0\u306E\u66F4\u65B0\u306B\u3064\u3044\u3066\u306F\u3001\u6B21\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044:\n{0}
 
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -1,79 +1,86 @@
-main.usage.summary=\u7528\u6CD5: {0} <\u9009\u9879> <\u8DEF\u5F84...>]\n\u4F7F\u7528 -h, -? \u6216 -help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
+main.usage.summary=\u7528\u6CD5: {0} <\u9009\u9879> <\u8DEF\u5F84 ...>]\n\u4F7F\u7528 -h, -?, -help \u6216 --help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
 
 main.usage=\u7528\u6CD5: {0} <\u9009\u9879> <\u8DEF\u5F84...>]\n\u5176\u4E2D <\u8DEF\u5F84> \u53EF\u4EE5\u662F .class \u6587\u4EF6, \u76EE\u5F55, JAR \u6587\u4EF6\u7684\u8DEF\u5F84\u540D\u3002\n\n\u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
 
 error.prefix=\u9519\u8BEF:
 warn.prefix=\u8B66\u544A:
 
-main.opt.h=\  -h -?        -help                \u8F93\u51FA\u6B64\u7528\u6CD5\u6D88\u606F
+main.opt.h=\  -h -? -help\n  --help                        \u8F93\u51FA\u6B64\u7528\u6CD5\u6D88\u606F
 
-main.opt.version=\  -version                          \u7248\u672C\u4FE1\u606F
+main.opt.version=\  -version --version            \u7248\u672C\u4FE1\u606F
 
-main.opt.v=\  -v           -verbose             \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     \u7B49\u540C\u4E8E -verbose:class -filter:none\u3002\n  -verbose:package                  \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n                                     \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n  -verbose:class                    \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n                                     \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61
+main.opt.v=\  -v       -verbose             \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                \u7B49\u540C\u4E8E -verbose:class -filter:none\u3002\n  -verbose:package              \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n                                \u5176\u4E2D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n  -verbose:class                \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n                                \u5176\u4E2D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61
 
-main.opt.s=\  -s           -summary             \u4EC5\u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981\u3002
+main.opt.s=\  -s       -summary             \u4EC5\u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981\u3002
 
-main.opt.f=\  -f <\u6B63\u5219\u8868\u8FBE\u5F0F>  -filter <\u6B63\u5219\u8868\u8FBE\u5F0F>       \u7B5B\u9009\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                    \u5982\u679C\u591A\u6B21\u6307\u5B9A, \u5219\u5C06\u4F7F\u7528\u6700\u540E\u4E00\u4E2A\n                                    \u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:package                   \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u7A0B\u5E8F\u5305\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                    \u8FD9\u662F\u9ED8\u8BA4\u503C\u3002\n  -filter:archive                   \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6863\u6848\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:module                    \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6A21\u5757\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:none                      \u4E0D\u4F7F\u7528 -filter:package \u548C -filter:archive \u7B5B\u9009\u3002\n                                    \u901A\u8FC7 -filter \u9009\u9879\u6307\u5B9A\u7684\u7B5B\u9009\n                                    \u4ECD\u65E7\u9002\u7528\u3002\n
-main.opt.p=\n\u7528\u4E8E\u7B5B\u9009\u88AB\u4F9D\u8D56\u5BF9\u8C61\u7684\u9009\u9879:\n  -p <\u7A0B\u5E8F\u5305\u540D> -package <\u7A0B\u5E8F\u5305\u540D> \u67E5\u627E\u4E0E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u540D\u79F0\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                    (\u53EF\u591A\u6B21\u6307\u5B9A)\u3002
+main.opt.f=\  -f <\u6B63\u5219\u8868\u8FBE\u5F0F>  -filter <\u6B63\u5219\u8868\u8FBE\u5F0F>    \u7B5B\u9009\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                    \u5982\u679C\u591A\u6B21\u6307\u5B9A, \u5219\u5C06\u4F7F\u7528\u6700\u540E\u4E00\u4E2A\n                                    \u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:package                   \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u7A0B\u5E8F\u5305\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                    \u8FD9\u662F\u9ED8\u8BA4\u503C\u3002\n  -filter:archive                   \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6863\u6848\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:module                \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6A21\u5757\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:none                  \u4E0D\u4F7F\u7528 -filter:package \u548C -filter:archive \u7B5B\u9009\u3002\n                                    \u901A\u8FC7 -filter \u9009\u9879\u6307\u5B9A\u7684\u7B5B\u9009\n                                    \u4ECD\u65E7\u9002\u7528\u3002\n
+main.opt.p=\n\u7528\u4E8E\u7B5B\u9009\u88AB\u4F9D\u8D56\u5BF9\u8C61\u7684\u9009\u9879:\n  -p <\u7A0B\u5E8F\u5305>\n  -package <\u7A0B\u5E8F\u5305>\n  --package <\u7A0B\u5E8F\u5305>            \u67E5\u627E\u4E0E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u540D\u79F0\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                (\u53EF\u591A\u6B21\u6307\u5B9A)\u3002
 
-main.opt.e=\  -e <\u6B63\u5219\u8868\u8FBE\u5F0F> -regex <\u6B63\u5219\u8868\u8FBE\u5F0F>         \u67E5\u627E\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
+main.opt.e=\  -e <\u6B63\u5219\u8868\u8FBE\u5F0F>\n  -regex <\u6B63\u5219\u8868\u8FBE\u5F0F>\n  --regex <\u6B63\u5219\u8868\u8FBE\u5F0F>               \u67E5\u627E\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
 
-main.opt.requires=\  -requires <\u6A21\u5757\u540D\u79F0>              \u67E5\u627E\u4E0E\u7ED9\u5B9A\u6A21\u5757\u540D\u79F0\u5339\u914D\u7684\n                                    \u88AB\u4F9D\u8D56\u5BF9\u8C61 (\u53EF\u591A\u6B21\u6307\u5B9A)\u3002\n                                    -package, -regex, -requires \u662F\u4E92\u65A5\u7684\u3002
+main.opt.require=\  --require <\u6A21\u5757\u540D\u79F0>          \u67E5\u627E\u4E0E\u7ED9\u5B9A\u6A21\u5757\u540D\u79F0\u5339\u914D\u7684\n                                \u88AB\u4F9D\u8D56\u5BF9\u8C61 (\u53EF\u591A\u6B21\u6307\u5B9A)\u3002--package,\n                                --regex, --requires \u662F\u4E92\u65A5\u7684\u3002
 
-main.opt.include=\n\u7528\u4E8E\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u9009\u9879:\n  -include <\u6B63\u5219\u8868\u8FBE\u5F0F>             \u5C06\u5206\u6790\u9650\u5236\u4E3A\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7C7B\n                                    \u6B64\u9009\u9879\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u5217\u8868\u3002\n                                    \u5B83\u53EF\u4EE5\u4E0E\u5411\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5E94\u7528\u6A21\u5F0F\u7684\n                                    -p \u548C -e \u7ED3\u5408\u4F7F\u7528
+main.opt.include=\n\u7528\u4E8E\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u9009\u9879:\n  -include <\u6B63\u5219\u8868\u8FBE\u5F0F>             \u5C06\u5206\u6790\u9650\u5236\u4E3A\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7C7B\n                                    \u6B64\u9009\u9879\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u5217\u8868\u3002\n                                    \u5B83\u53EF\u4EE5\u4E0E\u5411\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5E94\u7528\u6A21\u5F0F\u7684\n                                -p \u548C -e \u7ED3\u5408\u4F7F\u7528
 
-main.opt.P=\  -P           -profile             \u663E\u793A\u5305\u542B\u7A0B\u5E8F\u5305\u7684\u914D\u7F6E\u6587\u4EF6
+main.opt.P=\  -P       -profile             \u663E\u793A\u5305\u542B\u7A0B\u5E8F\u5305\u7684\u914D\u7F6E\u6587\u4EF6
 
-main.opt.cp=\  -cp <\u8DEF\u5F84>   -classpath <\u8DEF\u5F84>    \u6307\u5B9A\u67E5\u627E\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+main.opt.cp=\  -cp <\u8DEF\u5F84>\n  -classpath <\u8DEF\u5F84>\n  --class-path <\u8DEF\u5F84>           \u6307\u5B9A\u67E5\u627E\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
 
-main.opt.mp=\  -mp <module path>...\n  -modulepath <module path>...      \u6307\u5B9A\u6A21\u5757\u8DEF\u5F84
+main.opt.module-path=\  --module-path <\u6A21\u5757\u8DEF\u5F84>      \u6307\u5B9A\u6A21\u5757\u8DEF\u5F84
 
-main.opt.upgrademodulepath=\  -upgrademodulepath <module path>...  \u6307\u5B9A\u5347\u7EA7\u6A21\u5757\u8DEF\u5F84
+main.opt.upgrade-module-path=\  --upgrade-module-path <\u6A21\u5757\u8DEF\u5F84>  \u6307\u5B9A\u5347\u7EA7\u6A21\u5757\u8DEF\u5F84
 
-main.opt.system=\  -system <java \u4E3B\u76EE\u5F55>               \u6307\u5B9A\u66FF\u4EE3\u7CFB\u7EDF\u6A21\u5757\u8DEF\u5F84
+main.opt.system=\  --system <java \u4E3B\u76EE\u5F55>        \u6307\u5B9A\u66FF\u4EE3\u7CFB\u7EDF\u6A21\u5757\u8DEF\u5F84
 
-main.opt.addmods=\  -addmods <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]\n                                    \u5C06\u6A21\u5757\u6DFB\u52A0\u5230\u6839\u96C6\u4EE5\u8FDB\u884C\u5206\u6790
+main.opt.add-modules=\  --add-modules <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...]\n                                \u5C06\u6A21\u5757\u6DFB\u52A0\u5230\u6839\u96C6\u4EE5\u8FDB\u884C\u5206\u6790
 
-main.opt.m=\  -m <\u6A21\u5757\u540D\u79F0>                  \u6307\u5B9A\u7528\u4E8E\u5206\u6790\u7684\u6839\u6A21\u5757
+main.opt.m=\  -m <\u6A21\u5757\u540D\u79F0>\n  --module <\u6A21\u5757\u540D\u79F0>        \u6307\u5B9A\u7528\u4E8E\u5206\u6790\u7684\u6839\u6A21\u5757
 
-main.opt.R=\  -R           -recursive           \u9012\u5F52\u904D\u5386\u6240\u6709\u8FD0\u884C\u65F6\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                    -R \u9009\u9879\u8868\u793A -filter:none\u3002\u5982\u679C\n                                    \u6307\u5B9A\u4E86 -p, -e, -f \u9009\u9879, \u5219\u53EA\u5206\u6790\n                                    \u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
+main.opt.R=\  -R       -recursive           \u9012\u5F52\u904D\u5386\u6240\u6709\u8FD0\u884C\u65F6\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                -R \u9009\u9879\u8868\u793A -filter:none\u3002\u5982\u679C\n                                \u6307\u5B9A\u4E86 -p, -e, -f \u9009\u9879, \u5219\u53EA\u5206\u6790\n                                \u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
 
-main.opt.I=\  -I           -inverse             \u6839\u636E\u5176\u4ED6\u6307\u5B9A\u9009\u9879\u5206\u6790\u88AB\u4F9D\u8D56\u5BF9\u8C61,\n                                    \u7136\u540E\u67E5\u627E\u76F4\u63A5\u548C\u95F4\u63A5\u4F9D\u8D56\u4E8E\u5339\u914D\n                                    \u8282\u70B9\u7684\u6240\u6709 Artifact\u3002\n                                    \u8FD9\u76F8\u5F53\u4E8E\u7F16\u8BD1\u65F6\u89C6\u56FE\u5206\u6790\u7684\n                                    \u9006\u5411, \u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981\u3002\n                                    \u6B64\u9009\u9879\u5FC5\u987B\u4E0E -requires, \n                                    -package \u6216 -regex \u9009\u9879\u4E00\u8D77\u4F7F\u7528\u3002
+main.opt.I=\  -I       --inverse            \u6839\u636E\u5176\u4ED6\u6307\u5B9A\u9009\u9879\u5206\u6790\u88AB\u4F9D\u8D56\u5BF9\u8C61,\n                                \u7136\u540E\u67E5\u627E\u76F4\u63A5\u548C\u95F4\u63A5\u4F9D\u8D56\u4E8E\u5339\u914D\n                                \u8282\u70B9\u7684\u6240\u6709 Artifact\u3002\n                                \u8FD9\u76F8\u5F53\u4E8E\u7F16\u8BD1\u65F6\u89C6\u56FE\u5206\u6790\u7684\n                                \u9006\u5411, \u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981\u3002\n                                \u6B64\u9009\u9879\u5FC5\u987B\u4E0E --require, \n                                --package \u6216 --regex \u9009\u9879\u4E00\u8D77\u4F7F\u7528\u3002
 
-main.opt.ct=\  -ct          -compile-time        \u8FC7\u6E21\u88AB\u4F9D\u8D56\u5BF9\u8C61\u7684\u7F16\u8BD1\u65F6\u89C6\u56FE,\n                                    \u4F8B\u5982 -R \u9009\u9879\u7684\u7F16\u8BD1\u65F6\u89C6\u56FE\u3002\n                                    \u6839\u636E\u5176\u4ED6\u6307\u5B9A\u9009\u9879\u5206\u6790\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                    \u5982\u679C\u4ECE\u76EE\u5F55, JAR \u6587\u4EF6\u6216\u6A21\u5757\u4E2D\n                                    \u627E\u5230\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u5219\u5C06\u5206\u6790\n                                    \u8BE5\u6240\u5728\u6863\u6848\u4E2D\u7684\u6240\u6709\u7C7B\u3002
+main.opt.compile-time=\  --compile-time                \u8FC7\u6E21\u88AB\u4F9D\u8D56\u5BF9\u8C61\u7684\u7F16\u8BD1\u65F6\u89C6\u56FE,\n                                \u4F8B\u5982 -R \u9009\u9879\u7684\u7F16\u8BD1\u65F6\u89C6\u56FE\u3002\n                                \u6839\u636E\u5176\u4ED6\u6307\u5B9A\u9009\u9879\u5206\u6790\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                \u5982\u679C\u4ECE\u76EE\u5F55, JAR \u6587\u4EF6\u6216\u6A21\u5757\u4E2D\n                                \u627E\u5230\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u5219\u5C06\u5206\u6790\n                                \u8BE5\u6240\u5728\u6863\u6848\u4E2D\u7684\u6240\u6709\u7C7B\u3002
 
-main.opt.apionly=\  -apionly                          \u901A\u8FC7\u516C\u5171\u7C7B (\u5305\u62EC\u5B57\u6BB5\u7C7B\u578B, \u65B9\u6CD5\u53C2\u6570\n                                     \u7C7B\u578B, \u8FD4\u56DE\u7C7B\u578B, \u53D7\u63A7\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B\n                                     \u7B49) \u7684\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u6210\u5458\u7684\u7B7E\u540D\n                                     \u9650\u5236\u5BF9 API (\u5373\u88AB\u4F9D\u8D56\u5BF9\u8C61)\n                                     \u8FDB\u884C\u5206\u6790\u3002
+main.opt.apionly=\  -apionly\n  --api-only                    \u901A\u8FC7\u516C\u5171\u7C7B (\u5305\u62EC\u5B57\u6BB5\u7C7B\u578B, \u65B9\u6CD5\n                                \u53C2\u6570\u7C7B\u578B, \u8FD4\u56DE\u7C7B\u578B, \u53D7\u63A7\u5F02\u5E38\u9519\u8BEF\n                                \u7C7B\u578B\u7B49) \u7684\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u6210\u5458\u7684\u7B7E\u540D\n                                \u9650\u5236\u5BF9 API (\u5373\u88AB\u4F9D\u8D56\u5BF9\u8C61)\n                                \u8FDB\u884C\u5206\u6790\u3002
 
-main.opt.genmoduleinfo=\  -genmoduleinfo <\u76EE\u5F55>             \u5728\u6307\u5B9A\u76EE\u5F55\u4E0B\u751F\u6210 module-info.java\u3002\n                                    \u5C06\u5206\u6790\u6307\u5B9A\u7684 JAR \u6587\u4EF6\u3002\n                                    \u6B64\u9009\u9879\u4E0D\u80FD\u4E0E -dotoutput \n                                    \u6216 -cp \u4E00\u8D77\u4F7F\u7528\u3002
+main.opt.generate-module-info=\  --generate-module-info <\u76EE\u5F55> \u5728\u6307\u5B9A\u76EE\u5F55\u4E0B\u751F\u6210 module-info.java\u3002\n                                \u5C06\u5206\u6790\u6307\u5B9A\u7684 JAR \u6587\u4EF6\u3002\n                                \u6B64\u9009\u9879\u4E0D\u80FD\u4E0E --dot-output \n                                \u6216 --class-path \u4E00\u8D77\u4F7F\u7528\u3002
 
-main.opt.check=\  -check <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...\n                                    \u5206\u6790\u6307\u5B9A\u6A21\u5757\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                    \u5B83\u8F93\u51FA\u6A21\u5757\u63CF\u8FF0\u7B26, \u5206\u6790\u4E4B\u540E\n                                    \u751F\u6210\u7684\u6A21\u5757\u88AB\u4F9D\u8D56\u5BF9\u8C61\u4EE5\u53CA\n                                    \u8F6C\u6362\u51CF\u5C11\u4E4B\u540E\u7684\u56FE\u5F62\u3002\u5B83\u8FD8\n                                    \u6807\u8BC6\u4EFB\u4F55\u672A\u4F7F\u7528\u7684\u5408\u683C\u5BFC\u51FA\u3002
+main.opt.check=\  --check <\u6A21\u5757\u540D\u79F0>[,<\u6A21\u5757\u540D\u79F0>...\n                                \u5206\u6790\u6307\u5B9A\u6A21\u5757\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                \u5B83\u8F93\u51FA\u6A21\u5757\u63CF\u8FF0\u7B26, \u5206\u6790\u4E4B\u540E\n                                \u751F\u6210\u7684\u6A21\u5757\u88AB\u4F9D\u8D56\u5BF9\u8C61\u4EE5\u53CA\n                                \u8F6C\u6362\u51CF\u5C11\u4E4B\u540E\u7684\u56FE\u5F62\u3002\u5B83\u8FD8\n                                \u6307\u793A\u4EFB\u4F55\u672A\u4F7F\u7528\u7684\u5408\u683C\u5BFC\u51FA\u3002
 
 
-main.opt.dotoutput=\  -dotoutput <\u76EE\u5F55>                  DOT \u6587\u4EF6\u8F93\u51FA\u7684\u76EE\u6807\u76EE\u5F55
+main.opt.dotoutput=\  -dotoutput <\u76EE\u5F55>\n  --dot-output <\u76EE\u5F55>            DOT \u6587\u4EF6\u8F93\u51FA\u7684\u76EE\u6807\u76EE\u5F55
 
-main.opt.jdkinternals=\  -jdkinternals                     \u5728 JDK \u5185\u90E8 API \u4E0A\u67E5\u627E\u7C7B\u7EA7\u522B\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                    \u9664\u975E\u6307\u5B9A\u4E86 -include \u9009\u9879, \u5426\u5219\u9ED8\u8BA4\u60C5\u51B5\u4E0B,\n                                    \u5B83\u5206\u6790 -classpath \u4E0A\u7684\u6240\u6709\u7C7B\u548C\u8F93\u5165\u6587\u4EF6\u3002\n                                    \u6B64\u9009\u9879\u4E0D\u80FD\u4E0E -p, -e \u548C -s \u9009\u9879\n                                    \u4E00\u8D77\u4F7F\u7528\u3002\n                                    \u8B66\u544A: \u65E0\u6CD5\u8BBF\u95EE JDK \u5185\u90E8 API\u3002
+main.opt.jdkinternals=\  -jdkinternals\n  --jdk-internals               \u5728 JDK \u5185\u90E8 API \u4E0A\u67E5\u627E\u7C7B\u7EA7\u522B\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                \u9664\u975E\u6307\u5B9A\u4E86 -include \u9009\u9879, \u5426\u5219\u9ED8\u8BA4\u60C5\u51B5\u4E0B,\n                                \u5B83\u5206\u6790 --class-path \u4E0A\u7684\u6240\u6709\u7C7B\u548C\u8F93\u5165\u6587\u4EF6\u3002\n                                \u6B64\u9009\u9879\u4E0D\u80FD\u4E0E -p, -e \u548C -s \u9009\u9879\n                                \u4E00\u8D77\u4F7F\u7528\u3002\n                                \u8B66\u544A: \u65E0\u6CD5\u8BBF\u95EE JDK \u5185\u90E8 API\u3002
 
-main.opt.depth=\  -depth=<\u6DF1\u5EA6>                     \u6307\u5B9A\u8FC7\u6E21\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5206\u6790\n                                    \u7684\u6DF1\u5EA6
+main.opt.depth=\  -depth=<\u6DF1\u5EA6>                 \u6307\u5B9A\u8FC7\u6E21\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5206\u6790\n                                \u7684\u6DF1\u5EA6
 
-main.opt.q=\  -q           -quiet               \u5728 \n                                    -genmoduleinfo \u8F93\u51FA\u4E2D\u4E0D\u663E\u793A\u7F3A\u5C11\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
+main.opt.q=\  -q       -quiet               \u5728 --generate-module-info \u8F93\u51FA\u4E2D\n                                \u4E0D\u663E\u793A\u7F3A\u5C11\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
+
+main.opt.multi-release=\  --multi-release <\u7248\u672C>        \u6307\u5B9A\u5904\u7406\u591A\u53D1\u884C\u7248 jar \u6587\u4EF6\u65F6\u7684\n                                \u7248\u672C\u3002<\u7248\u672C> \u5E94\u4E3A\u5927\u4E8E\u7B49\u4E8E 9 \n                                \u7684\u6574\u6570\u6216\u57FA\u6570\u3002
 
 err.unknown.option=\u672A\u77E5\u9009\u9879: {0}
 err.missing.arg=\u6CA1\u6709\u4E3A{0}\u6307\u5B9A\u503C
 err.invalid.arg.for.option=\u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}
 err.option.after.class=\u5FC5\u987B\u5728\u7C7B\u4E4B\u524D\u6307\u5B9A\u9009\u9879: {0}
-err.genmoduleinfo.not.jarfile={0} \u5BF9 -genmoduleinfo \u9009\u9879\u65E0\u6548 (\u5FC5\u987B\u4E3A\u975E\u6A21\u5757\u5316 JAR \u6587\u4EF6)
+err.genmoduleinfo.not.jarfile={0} \u662F\u65E0\u6CD5\u4F7F\u7528 --generate-module-info \u9009\u9879\u6307\u5B9A\u7684\u6A21\u5757\u5316 JAR \u6587\u4EF6
+err.genmoduleinfo.unnamed.package={0} \u5305\u542B\u6A21\u5757\u4E2D\u4E0D\u5141\u8BB8\u7684\u672A\u547D\u540D\u7A0B\u5E8F\u5305
 err.profiles.msg=\u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u4FE1\u606F
 err.exception.message={0}
 err.invalid.path=\u65E0\u6548\u8DEF\u5F84: {0}
 err.invalid.module.option=\u65E0\u6CD5\u4F7F\u7528 {1} \u9009\u9879\u8BBE\u7F6E {0}\u3002
-err.invalid.filters=\u53EA\u80FD\u8BBE\u7F6E -package (-p), -regex (-e), -requires \u9009\u9879\u4E2D\u7684\u4E00\u4E2A
+err.invalid.filters=\u53EA\u80FD\u8BBE\u7F6E --package (-p), --regex (-e), --require \u9009\u9879\u4E2D\u7684\u4E00\u4E2A
 err.module.not.found=\u627E\u4E0D\u5230\u6A21\u5757: {0}
 err.root.module.not.set=\u6839\u6A21\u5757\u96C6\u4E3A\u7A7A
-err.invalid.inverse.option={0} \u4E0D\u80FD\u4E0E -inverse \u9009\u9879\u4E00\u8D77\u4F7F\u7528
-err.inverse.filter.not.set={0} \u4E0D\u80FD\u4E0E -inverse \u9009\u9879\u4E00\u8D77\u4F7F\u7528
+err.invalid.inverse.option={0} \u4E0D\u80FD\u4E0E --inverse \u9009\u9879\u4E00\u8D77\u4F7F\u7528
+err.multirelease.option.exists={0} \u4E0D\u662F\u591A\u53D1\u884C\u7248 jar \u6587\u4EF6, \u4F46\u8BBE\u7F6E\u4E86 --multi-release \u9009\u9879
+err.multirelease.option.notfound={0} \u662F\u591A\u53D1\u884C\u7248 jar \u6587\u4EF6, \u4F46\u672A\u8BBE\u7F6E --multi-release \u9009\u9879
+err.multirelease.version.associated=\u7C7B {0} \u5DF2\u4E0E\u7248\u672C {1} \u5173\u8054, \u6B63\u5728\u5C1D\u8BD5\u6DFB\u52A0\u7248\u672C {2}
+err.multirelease.jar.malformed=\u683C\u5F0F\u9519\u8BEF\u7684\u591A\u53D1\u884C\u7248 jar, {0}, \u9519\u8BEF\u6761\u76EE: {1}
 warn.invalid.arg=\u8DEF\u5F84\u4E0D\u5B58\u5728: {0}
+warn.skipped.entry={0}
 warn.split.package=\u5DF2\u5728{1} {2}\u4E2D\u5B9A\u4E49\u7A0B\u5E8F\u5305{0}
-warn.replace.useJDKInternals=\u4E0D\u652F\u6301 JDK \u5185\u90E8 API, \u5B83\u4EEC\u4E13\u7528\u4E8E\u901A\u8FC7\u4E0D\u517C\u5BB9\u65B9\u5F0F\u6765\u5220\u9664\n\u6216\u66F4\u6539\u7684 JDK \u5B9E\u73B0, \u53EF\u80FD\u4F1A\u635F\u574F\u60A8\u7684\u5E94\u7528\u7A0B\u5E8F\u3002\n\u8BF7\u4FEE\u6539\u60A8\u7684\u4EE3\u7801, \u6D88\u9664\u4E0E\u4EFB\u4F55 JDK \u5185\u90E8 API \u7684\u76F8\u5173\u6027\u3002\n\u6709\u5173 JDK \u5185\u90E8 API \u66FF\u6362\u7684\u6700\u65B0\u66F4\u65B0, \u8BF7\u67E5\u770B:\n{0}
+warn.replace.useJDKInternals=\u4E0D\u652F\u6301 JDK \u5185\u90E8 API, \u5B83\u4EEC\u4E13\u7528\u4E8E\u901A\u8FC7\u4E0D\u517C\u5BB9\u65B9\u5F0F\u6765\n\u5220\u9664\u6216\u66F4\u6539\u7684 JDK \u5B9E\u73B0, \u53EF\u80FD\u4F1A\u635F\u574F\u60A8\u7684\u5E94\u7528\u7A0B\u5E8F\u3002\n\u8BF7\u4FEE\u6539\u60A8\u7684\u4EE3\u7801, \u6D88\u9664\u4E0E\u4EFB\u4F55 JDK \u5185\u90E8 API \u7684\u76F8\u5173\u6027\u3002\n\u6709\u5173 JDK \u5185\u90E8 API \u66FF\u6362\u7684\u6700\u65B0\u66F4\u65B0, \u8BF7\u67E5\u770B:\n{0}
 
 artifact.not.found=\u627E\u4E0D\u5230
 jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n_ja.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n_ja.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,10 +24,11 @@
 #
 
 jshell.msg.welcome =JShell\u3078\u3088\u3046\u3053\u305D -- \u30D0\u30FC\u30B8\u30E7\u30F3{0}\n\u6982\u8981\u306B\u3064\u3044\u3066\u306F\u3001\u6B21\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: /help intro\n
-jshell.err.opt.classpath.conflict = -classpath\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u7AF6\u5408\u3057\u3066\u3044\u307E\u3059\u3002
-jshell.err.opt.classpath.arg = -classpath\u3078\u306E\u5F15\u6570\u304C\u3042\u308A\u307E\u305B\u3093\u3002
-jshell.err.opt.feedback.arg = -feedback\u306E\u5F15\u6570\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u30E2\u30FC\u30C9\u306F\u5FC5\u9808\u3067\u3059\u3002
-jshell.err.opt.startup.one = -startup\u307E\u305F\u306F-nostartup\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
+jshell.err.opt.arg = {0}\u3078\u306E\u5F15\u6570\u304C\u3042\u308A\u307E\u305B\u3093\u3002
+jshell.err.opt.invalid = \u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}\u3002
+jshell.err.opt.one = {0}\u30AA\u30D7\u30B7\u30E7\u30F3\u306F1\u3064\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
+jshell.err.opt.startup.one = --startup\u307E\u305F\u306F--no-startup\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
+jshell.err.opt.feedback.one = \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3(--feedback\u3001-q\u3001-s\u307E\u305F\u306F-v)\u306F1\u3064\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
 jshell.err.opt.unknown = \u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
 
 jshell.msg.terminated =\u72B6\u614B\u30A8\u30F3\u30B8\u30F3\u304C\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002\n\u6B21\u3092\u6307\u5B9A\u3057\u3066\u5B9A\u7FA9\u3092\u5FA9\u5143\u3057\u3066\u304F\u3060\u3055\u3044: /reload -restore
@@ -47,10 +48,16 @@
 
 jshell.err.no.such.command.or.snippet.id = \u6307\u5B9A\u3055\u308C\u305F\u30B3\u30DE\u30F3\u30C9\u307E\u305F\u306F\u30B9\u30CB\u30DA\u30C3\u30C8ID\u306F\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
 jshell.err.command.ambiguous = \u30B3\u30DE\u30F3\u30C9: ''{0}''\u306F\u3042\u3044\u307E\u3044\u3067\u3059: {1}
-jshell.err.set.editor.arg = ''/set editor''\u30B3\u30DE\u30F3\u30C9\u306B\u306F\u30D1\u30B9\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3059
 jshell.msg.set.editor.set = \u30A8\u30C7\u30A3\u30BF\u306F\u6B21\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059: {0}
+jshell.msg.set.editor.retain = \u30A8\u30C7\u30A3\u30BF\u8A2D\u5B9A\u304C\u4FDD\u6301\u3055\u308C\u3066\u3044\u307E\u3059: {0}
 jshell.err.cant.launch.editor = \u30A8\u30C7\u30A3\u30BF\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093 -- \u4E88\u671F\u3057\u306A\u3044\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}
 jshell.msg.try.set.editor = \u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u3092\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001/set editor\u3092\u5B9F\u884C\u3057\u3066\u3057\u3066\u304F\u3060\u3055\u3044\u3002
+jshell.msg.press.return.to.leave.edit.mode = \u300C\u623B\u308B\u300D\u3092\u62BC\u3059\u3068\u7DE8\u96C6\u30E2\u30FC\u30C9\u304C\u7D42\u4E86\u3057\u307E\u3059\u3002
+jshell.err.wait.applies.to.external.editor = -wait\u306F\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u306B\u9069\u7528\u3055\u308C\u307E\u3059
+
+jshell.err.setting.to.retain.must.be.specified = \u4FDD\u6301\u3059\u308B\u8A2D\u5B9A\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 -- {0}
+jshell.msg.set.show.mode.settings = \n\u30E2\u30FC\u30C9\u8A2D\u5B9A\u3092\u8868\u793A\u3059\u308B\u306B\u306F\u3001''/set prompt''\u3001''/set truncation'' ...\u3092\u4F7F\u7528\u3059\u308B\u304B\u3001\n''/set mode''\u306E\u5F8C\u306B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u540D\u3092\u7D9A\u3051\u3066\u4F7F\u7528\u3057\u307E\u3059\u3002
+jshell.err.continuation.prompt.required = \u7D9A\u884C\u30D7\u30ED\u30F3\u30D7\u30C8\u304C\u5FC5\u8981\u3067\u3059 -- {0}
 
 jshell.msg.try.command.without.args = \u5F15\u6570\u3092\u6307\u5B9A\u305B\u305A\u306B''{0}''\u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 jshell.msg.no.active = \u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u5B9A\u7FA9\u304C\u3042\u308A\u307E\u305B\u3093\u3002
@@ -91,12 +98,10 @@
 jshell.err.mode.name = \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u540D\u304C\u5FC5\u8981\u3067\u3059: {0}
 jshell.err.missing.mode = \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u304C\u3042\u308A\u307E\u305B\u3093 -- {0}
 jshell.err.field.name = \u30D5\u30A3\u30FC\u30EB\u30C9\u540D\u304C\u5FC5\u8981\u3067\u3059: {0} -- {1}
-jshell.err.missing.field = \u30D5\u30A3\u30FC\u30EB\u30C9\u540D\u304C\u3042\u308A\u307E\u305B\u3093 -- {0}
 jshell.err.mode.unknown = \u540D\u524D{0}\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u304C\u3042\u308A\u307E\u305B\u3093 -- {1}
 
 jshell.err.feedback.does.not.match.mode = \u73FE\u5728\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093: {0} -- {1}
 jshell.err.feedback.ambiguous.mode = \u8907\u6570\u306E\u73FE\u5728\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3068\u4E00\u81F4\u3057\u307E\u3059: {0} -- {1}
-jshell.err.feedback.expected.format = \u5FC5\u8981\u306A\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304C\u3042\u308A\u307E\u305B\u3093 -- {0}
 jshell.err.feedback.must.be.quoted = \u30D5\u30A9\u30FC\u30DE\u30C3\u30C8''{0}''\u306F\u5F15\u7528\u7B26\u3067\u56F2\u3080\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 -- {1}
 jshell.err.feedback.not.a.valid.selector = ''{1}''\u306E\u6709\u52B9\u306A\u30BB\u30EC\u30AF\u30BF''{0}''\u3067\u306F\u3042\u308A\u307E\u305B\u3093 -- {2}
 jshell.err.feedback.multiple.sections = ''{1}''\u306E\u30BB\u30EC\u30AF\u30BF\u30FB\u30EA\u30B9\u30C8''{0}''\u306E\u8907\u6570\u30BB\u30AF\u30B7\u30E7\u30F3\u5185\u306E\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E -- {2}
@@ -104,21 +109,24 @@
 
 jshell.msg.feedback.new.mode = \u65B0\u898F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F: {0}
 jshell.msg.feedback.mode = \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9: {0}
-jshell.msg.feedback.mode.following = \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306F\u6B21\u306E\u3044\u305A\u308C\u304B\u306B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059:
+jshell.msg.feedback.mode.following = \u4F7F\u7528\u53EF\u80FD\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9:
+jshell.msg.feedback.retained.mode.following = \u4FDD\u6301\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9:
+jshell.err.mode.creation = \u65B0\u3057\u3044\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u3059\u308B\u306B\u306F\u3001-command\u307E\u305F\u306F-quiet\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 -- {0}
+jshell.err.mode.exists = \u4F5C\u6210\u3055\u308C\u308B\u30E2\u30FC\u30C9\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059: {0} -- {1}
 
 jshell.err.truncation.expected.length = \u5207\u6368\u3066\u9577\u304C\u5FC5\u8981\u3067\u3059 -- {0}
 jshell.err.truncation.length.not.integer = \u5207\u6368\u3066\u9577\u306F\u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0} -- {1}
 
 jshell.err.not.valid.with.predefined.mode = \u4E8B\u524D\u5B9A\u7FA9\u6E08\u30E2\u30FC\u30C9\u3067\u306F\u6709\u52B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093: {0} -- {1}
-jshell.err.retained.feedback.mode.must.be.retained.or.predefined = ''/retain feedback <mode>''\u3067\u306F\u3001<mode>\u304C\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B\u304B\u3001''/retain mode''\u3067\u4FDD\u6301\u3055\u308C\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 -- {0}
+jshell.err.retained.feedback.mode.must.be.retained.or.predefined = ''/set feedback -retain <mode>''\u3067\u306F\u3001<mode>\u304C\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B\u304B\u3001''/set mode -retain''\u3067\u4FDD\u6301\u3055\u308C\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 -- {0}
 
 jshell.err.unknown.option = \u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0} -- {1}
-jshell.err.default.option.or.program = -default\u30AA\u30D7\u30B7\u30E7\u30F3\u307E\u305F\u306F\u30D7\u30ED\u30B0\u30E9\u30E0\u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 -- {0}
-jshell.err.option.or.filename = 1\u3064\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u307E\u305F\u306F\u8D77\u52D5\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 -- {0}
+jshell.err.default.option.or.program = -default\u30AA\u30D7\u30B7\u30E7\u30F3\u3001-delete\u30AA\u30D7\u30B7\u30E7\u30F3\u307E\u305F\u306F\u30D7\u30ED\u30B0\u30E9\u30E0\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 -- {0}
+jshell.err.option.or.filename = -default\u3001-none\u307E\u305F\u306F\u8D77\u52D5\u30D5\u30A1\u30A4\u30EB\u540D\u306E\u3044\u305A\u308C\u304B\u30921\u3064\u306E\u307F\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 -- {0}
 jshell.err.unexpected.at.end = \u30B3\u30DE\u30F3\u30C9\u306E\u7D42\u308F\u308A\u306B\u4E88\u671F\u3057\u306A\u3044\u5F15\u6570\u304C\u3042\u308A\u307E\u3059: {0} -- {1}
 jshell.err.conflicting.options = \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u7AF6\u5408\u3057\u3066\u3044\u307E\u3059 -- {0}
 jshell.err.cannot.delete.current.mode = \u73FE\u5728\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9''{0}''\u306F\u524A\u9664\u3067\u304D\u307E\u305B\u3093\u3002\u6700\u521D\u306B''/set feedback''\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044 -- {1}
-jshell.err.cannot.delete.retained.mode = \u4FDD\u6301\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9''{0}''\u306F\u524A\u9664\u3067\u304D\u307E\u305B\u3093\u3002\u6700\u521D\u306B''/retain feedback''\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044 -- {1}
+jshell.err.cannot.delete.retained.mode = \u4FDD\u6301\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9''{0}''\u306F\u524A\u9664\u3067\u304D\u307E\u305B\u3093\u3002\u6700\u521D\u306B''/set feedback -retain''\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044 -- {1}
 jshell.err.may.not.specify.options.and.snippets = \u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u4E21\u65B9\u3092\u4F7F\u7528\u3057\u3066\u306F\u3044\u3051\u307E\u305B\u3093: {0}
 jshell.err.no.such.snippets = \u6307\u5B9A\u3055\u308C\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u306F\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
 jshell.err.the.snippet.cannot.be.used.with.this.command = \u3053\u306E\u30B3\u30DE\u30F3\u30C9\u306F\u30B9\u30CB\u30DA\u30C3\u30C8''{0}''\u3092\u53D7\u3051\u5165\u308C\u307E\u305B\u3093: {1}
@@ -126,14 +134,15 @@
 
 jshell.console.see.more = <\u8A73\u7D30\u306F\u3001\u30BF\u30D6\u3092\u62BC\u3057\u3066\u304F\u3060\u3055\u3044>
 jshell.console.do.nothing = \u4F55\u3082\u3057\u306A\u3044
-jshell.console.choice = \u9078\u629E:
+jshell.console.choice = \u9078\u629E: 
 jshell.console.create.variable = \u5909\u6570\u306E\u4F5C\u6210
 jshell.console.resolvable = \n\u8B58\u5225\u5B50\u306F\u3053\u306E\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u89E3\u6C7A\u3067\u304D\u307E\u3059\u3002
 jshell.console.no.candidate = \n\u30A4\u30F3\u30DD\u30FC\u30C8\u3059\u308B\u5019\u88DC\u306E\u5B8C\u5168\u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002
 jshell.console.incomplete = \n\u7D50\u679C\u304C\u4E0D\u5B8C\u5168\u3067\u3042\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u7D50\u679C\u3092\u5B8C\u5168\u306B\u3059\u308B\u306B\u306F\u3001\u5F8C\u3067\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 
 
-help.usage = \u4F7F\u7528\u65B9\u6CD5:   jshell <options> <load files>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059:\n    -classpath <path>          \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059\n    -cp <path>                 \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059\n    -startup <file>            \u8D77\u52D5\u5B9A\u7FA9\u306E\u4EE3\u66FF\u3068\u3057\u3066\u5B9F\u884C\u3055\u308C\u307E\u3059\n    -nostartup                 \u8D77\u52D5\u5B9A\u7FA9\u3092\u5B9F\u884C\u3057\u307E\u305B\u3093\n    -feedback <mode>     \u521D\u671F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u30E2\u30FC\u30C9\u306F\n                         \u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B(silent\u3001concise\u3001normal\u307E\u305F\u306Fverbose)\u304B\u3001\n                         \u4E8B\u524D\u306B\u30E6\u30FC\u30B6\u30FC\u304C\u5B9A\u7FA9\u3067\u304D\u307E\u3059\n    -q                   \u7C21\u6F54\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3002-feedback concise\u3068\u540C\u3058\n    -qq                  \u975E\u5E38\u306B\u7C21\u6F54\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3002-feedback silent\u3068\u540C\u3058\n    -v                   \u8A73\u7D30\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3002-feedback verbose\u3068\u540C\u3058\n    -J<flag>             <flag>\u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3057\u307E\u3059\u3002\n                         \u5B9F\u884C\u6642\u30D5\u30E9\u30B0\u307E\u305F\u306F\u30D5\u30E9\u30B0\u5F15\u6570\u3054\u3068\u306B1\u3064\u306E-J\u3092\u4F7F\u7528\u3057\u307E\u3059\n    -R<flag>             <flag>\u3092\u30EA\u30E2\u30FC\u30C8\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u6E21\u3057\u307E\u3059\u3002\n                         \u30EA\u30E2\u30FC\u30C8\u30FB\u30D5\u30E9\u30B0\u307E\u305F\u306F\u30D5\u30E9\u30B0\u5F15\u6570\u3054\u3068\u306B1\u3064\u306E-R\u3092\u4F7F\u7528\u3057\u307E\u3059\n    -help                      \u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u307E\u3059\n    -version                   \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\n
+help.usage = \u4F7F\u7528\u65B9\u6CD5:   jshell <options> <load files>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059:\n    --class-path <path>   \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059\n    --module-path <path>  \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059\n    --add-modules <module>(,<module>)*\n                          \u89E3\u6C7A\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3001\u307E\u305F\u306F<module>\u304CALL-MODULE-PATH\n                           \u3067\u3042\u308B\u5834\u5408\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\n    --startup <file>      \u8D77\u52D5\u5B9A\u7FA9\u306E\u4EE3\u66FF\u3068\u3057\u3066\u5B9F\u884C\u3055\u308C\u307E\u3059\n    --no-startup          \u8D77\u52D5\u5B9A\u7FA9\u3092\u5B9F\u884C\u3057\u307E\u305B\u3093\n    --feedback <mode>     \u521D\u671F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u30E2\u30FC\u30C9\u306F\n                           \u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B(silent\u3001concise\u3001normal\u307E\u305F\u306Fverbose)\u304B\u3001\n                           \u4E8B\u524D\u306B\u30E6\u30FC\u30B6\u30FC\u304C\u5B9A\u7FA9\u3067\u304D\u307E\u3059\n    -q                    \u7C21\u6F54\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3002--feedback concise\u3068\u540C\u3058\n    -s                    \u975E\u5E38\u306B\u7C21\u6F54\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3002--feedback silent\u3068\u540C\u3058\n    -v                    \u8A73\u7D30\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3002--feedback verbose\u3068\u540C\u3058\n    -J<flag>              <flag>\u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3057\u307E\u3059\u3002\n                            \u5B9F\u884C\u6642\u30D5\u30E9\u30B0\u307E\u305F\u306F\u30D5\u30E9\u30B0\u5F15\u6570\u3054\u3068\u306B1\u3064\u306E-J\u3092\u4F7F\u7528\u3057\u307E\u3059\n    -R<flag>              <flag>\u3092\u30EA\u30E2\u30FC\u30C8\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u6E21\u3057\u307E\u3059\u3002\n                            \u30EA\u30E2\u30FC\u30C8\u30FB\u30D5\u30E9\u30B0\u307E\u305F\u306F\u30D5\u30E9\u30B0\u5F15\u6570\u3054\u3068\u306B1\u3064\u306E-R\u3092\u4F7F\u7528\u3057\u307E\u3059\n    -C<flag>              <flag>\u3092\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u6E21\u3057\u307E\u3059\u3002\n                            \u30B3\u30F3\u30D1\u30A4\u30E9\u30FB\u30D5\u30E9\u30B0\u307E\u305F\u306F\u30D5\u30E9\u30B0\u5F15\u6570\u3054\u3068\u306B1\u3064\u306E-C\u3092\u4F7F\u7528\u3057\u307E\u3059\n    --help                \u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u307E\u3059\n    --version             \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\n    -X                    \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3057\u307E\u3059\n
+help.usage.x = \    --add-exports <module>/<package>   \u6307\u5B9A\u3057\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u56FA\u6709\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30B9\u30CB\u30DA\u30C3\u30C8\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3057\u307E\u3059\n    \n\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\n
 
 help.list.summary = \u5165\u529B\u3057\u305F\u30BD\u30FC\u30B9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059
 help.list.args = [<name or id>|-all|-start]
@@ -181,7 +190,7 @@
 
 help.reload.summary = \u30EA\u30BB\u30C3\u30C8\u3057\u3066\u95A2\u9023\u3059\u308B\u5C65\u6B74\u3092\u30EA\u30D7\u30EC\u30A4\u3057\u307E\u3059 -- \u73FE\u5728\u307E\u305F\u306F\u4EE5\u524D(-restore)
 help.reload.args = [-restore] [-quiet]
-help.reload =jshell\u30C4\u30FC\u30EB\u30FB\u30B3\u30FC\u30C9\u304A\u3088\u3073\u5B9F\u884C\u72B6\u614B\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u3001\u5404jshell\u6709\u52B9\u30B3\u30DE\u30F3\u30C9\n\u304A\u3088\u3073\u6709\u52B9\u30B9\u30CB\u30DA\u30C3\u30C8\u3092\u5165\u529B\u3055\u308C\u305F\u9806\u756A\u3067\u30EA\u30D7\u30EC\u30A4\u3057\u307E\u3059\u3002\n\n/reload\n\t\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u3001jshell\u304C\u5165\u529B\u3055\u308C\u305F\u3001\u3042\u308B\u3044\u306F/reset\u307E\u305F\u306F\n\t/reload\u30B3\u30DE\u30F3\u30C9\u304C\u5B9F\u884C\u3055\u308C\u305F(\u6700\u65B0\u306E\u3044\u305A\u308C\u304B)\u4EE5\u964D\u306E\u6709\u52B9\u306A\u5C65\u6B74\u304C\n\t\u30EA\u30D7\u30EC\u30A4\u3055\u308C\u307E\u3059\u3002\n\n/reload -restore\n\t\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u3001jshell\u304C\u5B9F\u884C\u3055\u308C\u305F\u3001\u3042\u308B\u3044\u306F/reset\u307E\u305F\u306F/reload\u30B3\u30DE\u30F3\u30C9\u304C\n\t\u5B9F\u884C\u3055\u308C\u305F\u4EE5\u524D\u3068\u6700\u65B0\u306E\u6642\u9593\u306E\u9593\u306E\u6709\u52B9\u306A\u5C65\u6B74\u304C\u30EA\u30D7\u30EC\u30A4\u3055\u308C\u307E\u3059\u3002\n\t\u305D\u306E\u305F\u3081\u3001\u3053\u308C\u306F\u4EE5\u524D\u306Ejshell\u30C4\u30FC\u30EB\u30FB\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u5FA9\u5143\u306B\n\t\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n\n/reload [-restore] -quiet\n\t'-quiet'\u5F15\u6570\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u30EA\u30D7\u30EC\u30A4\u304C\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3002\u30A8\u30E9\u30FC\u306F\u8868\u793A\u3055\u308C\u307E\u3059\u3002
+help.reload =jshell\u30C4\u30FC\u30EB\u30FB\u30B3\u30FC\u30C9\u304A\u3088\u3073\u5B9F\u884C\u72B6\u614B\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u3001\u5404\u6709\u52B9\u30B9\u30CB\u30DA\u30C3\u30C8\n\u304A\u3088\u3073\u4EFB\u610F\u306E/drop\u307E\u305F\u306F/classpath\u30B3\u30DE\u30F3\u30C9\u3092\u5165\u529B\u3055\u308C\u305F\u9806\u756A\u3067\u30EA\u30D7\u30EC\u30A4\u3057\u307E\u3059\u3002\n\n/reload\n\t\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u3001jshell\u304C\u5165\u529B\u3055\u308C\u305F\u3001\u3042\u308B\u3044\u306F/reset\u307E\u305F\u306F\n\t/reload\u30B3\u30DE\u30F3\u30C9\u304C\u5B9F\u884C\u3055\u308C\u305F(\u6700\u65B0\u306E\u3044\u305A\u308C\u304B)\u4EE5\u964D\u306E\u6709\u52B9\u306A\u5C65\u6B74\u304C\n\t\u30EA\u30D7\u30EC\u30A4\u3055\u308C\u307E\u3059\u3002\n\n/reload -restore\n\t\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u3001jshell\u304C\u5165\u529B\u3055\u308C\u305F\u3001\u3042\u308B\u3044\u306F/reset\u307E\u305F\u306F/reload\u30B3\u30DE\u30F3\u30C9\u304C\n\t\u5B9F\u884C\u3055\u308C\u305F\u4EE5\u524D\u3068\u6700\u65B0\u306E\u6642\u9593\u306E\u9593\u306E\u6709\u52B9\u306A\u5C65\u6B74\u304C\u30EA\u30D7\u30EC\u30A4\u3055\u308C\u307E\u3059\u3002\n\t\u305D\u306E\u305F\u3081\u3001\u3053\u308C\u306F\u4EE5\u524D\u306Ejshell\u30C4\u30FC\u30EB\u30FB\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u5FA9\u5143\u306B\n\t\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n\n/reload [-restore] -quiet\n\t'-quiet'\u5F15\u6570\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u30EA\u30D7\u30EC\u30A4\u304C\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3002\u30A8\u30E9\u30FC\u306F\u8868\u793A\u3055\u308C\u307E\u3059\u3002
 
 help.classpath.summary = \u30AF\u30E9\u30B9\u30D1\u30B9\u306B\u30D1\u30B9\u3092\u8FFD\u52A0\u3057\u307E\u3059
 help.classpath.args = <path>
@@ -201,11 +210,7 @@
 
 help.set.summary = jshell\u69CB\u6210\u60C5\u5831\u3092\u8A2D\u5B9A\u3057\u307E\u3059
 help.set.args = editor|start|feedback|mode|prompt|truncation|format ...
-help.set =\u6B21\u306E\u3088\u3046\u306Ajshell\u69CB\u6210\u60C5\u5831\u3092\u8A2D\u5B9A\u3057\u307E\u3059:\n\u4F7F\u7528\u3059\u308B\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u3001\u4F7F\u7528\u3059\u308B\u8D77\u52D5\u5B9A\u7FA9\u3001\u65B0\u898F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3001\n\u30B3\u30DE\u30F3\u30C9\u30FB\u30D7\u30ED\u30F3\u30D7\u30C8\u3001\u4F7F\u7528\u3059\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u307E\u305F\u306F\u51FA\u529B\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3002\n\n/set editor <command> <optional-arg>...\n\t/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n\t<command>\u306F\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u4F9D\u5B58\u6587\u5B57\u5217\u3067\u3059\u3002\n\n/set start <file>\n\t\u6307\u5B9A\u3057\u305F<file>\u306E\u5185\u5BB9\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u306A\u308A\u307E\u3059\u3002\n\n/set feedback <mode>\n\t\u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u793A\u3059\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\t\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u307E\u305F\u306F\u66F4\u65B0\u3057\u307E\u3059\u3002\u5FC5\u8981\u306B\u5FDC\u3058\u3066\u65E2\u5B58\u306E\u30E2\u30FC\u30C9\u304B\u3089\u30B3\u30D4\u30FC\u3057\u307E\u3059\u3002\n\n/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\u6307\u5B9A\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n/set truncation <mode> <length> <selector>...\n\t\u8868\u793A\u3055\u308C\u308B\u5024\u306E\u6700\u5927\u9577\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n/set format <mode> <field> "<format>" <selector>...\n\t\u30BB\u30EC\u30AF\u30BF\u304C\u4E00\u81F4\u3057\u305F\u969B\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u8A2D\u5B9A\u3059\u308B\u3053\u3068\u3067\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u69CB\u6210\u3057\u307E\u3059\u3002\n\n\u3053\u308C\u3089\u306E\u5F62\u5F0F\u306E\u8A73\u7D30\u306F\u3001\u5F62\u5F0F\u3092\u6307\u5B9A\u3057\u3066/help\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u4F8B:   /help /set format
-
-help.retain.summary = \u5F8C\u7D9A\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306B\u5BFE\u3057\u3066jshell\u69CB\u6210\u60C5\u5831\u3092\u4FDD\u6301\u3057\u307E\u3059
-help.retain.args = editor|start|feedback|mode
-help.retain =jshell\u30C4\u30FC\u30EB\u306E\u4ECA\u5F8C\u306E\u547C\u51FA\u3057\u306B\u5BFE\u3057\u3066\u3001\u6B21\u306E\u3088\u3046\u306Ajshell\u69CB\u6210\u60C5\u5831\u3092\u4FDD\u6301\u3057\u307E\u3059:\n\u4F7F\u7528\u3059\u308B\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u3001\u4F7F\u7528\u3059\u308B\u8D77\u52D5\u5B9A\u7FA9\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u69CB\u6210\u3001\n\u307E\u305F\u306F\u4F7F\u7528\u3059\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3002\n\n/retain editor <command> <optional-arg>...\n\t/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n\t<command>\u306F\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u4F9D\u5B58\u6587\u5B57\u5217\u3067\u3059\u3002\n\n/retain start <file>\n\t\u6307\u5B9A\u3057\u305F<file>\u306E\u5185\u5BB9\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u306A\u308A\u307E\u3059\u3002\n\n/retain feedback <mode>\n\t\u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u793A\u3059\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n/retain mode <mode>\n\t\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002\u5FC5\u8981\u306B\u5FDC\u3058\u3066\u65E2\u5B58\u306E\u30E2\u30FC\u30C9\u304B\u3089\u30B3\u30D4\u30FC\u3057\u307E\u3059\u3002\n\n\u3053\u308C\u3089\u306E\u5F62\u5F0F\u306E\u8A73\u7D30\u306F\u3001\u5F62\u5F0F\u3092\u6307\u5B9A\u3057\u3066/help\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u4F8B:    /help /retain feedback
+help.set =\u6B21\u306E\u3088\u3046\u306Ajshell\u69CB\u6210\u60C5\u5831\u3092\u8A2D\u5B9A\u3057\u307E\u3059:\n\u4F7F\u7528\u3059\u308B\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u3001\u4F7F\u7528\u3059\u308B\u8D77\u52D5\u5B9A\u7FA9\u3001\u65B0\u898F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3001\n\u30B3\u30DE\u30F3\u30C9\u30FB\u30D7\u30ED\u30F3\u30D7\u30C8\u3001\u4F7F\u7528\u3059\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u307E\u305F\u306F\u51FA\u529B\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3002\n\n/set editor [-wait] <command> <optional-arg>...\n\t/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n\t<command>\u306F\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u4F9D\u5B58\u6587\u5B57\u5217\u3067\u3059\u3002\n\n/set start <file>\n\t\u6307\u5B9A\u3057\u305F<file>\u306E\u5185\u5BB9\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u306A\u308A\u307E\u3059\u3002\n\n/set feedback <mode>\n\t\u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u793A\u3059\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n/set mode <mode> [<old-mode>] -command|-quiet|-delete\n\t\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u307E\u305F\u306F\u66F4\u65B0\u3057\u307E\u3059\u3002\u5FC5\u8981\u306B\u5FDC\u3058\u3066\u65E2\u5B58\u306E\u30E2\u30FC\u30C9\u304B\u3089\u30B3\u30D4\u30FC\u3057\u307E\u3059\u3002\n\n/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\u6307\u5B9A\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n/set truncation <mode> <length> <selector>...\n\t\u8868\u793A\u3055\u308C\u308B\u5024\u306E\u6700\u5927\u9577\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n/set format <mode> <field> "<format>" <selector>...\n\t\u30BB\u30EC\u30AF\u30BF\u304C\u4E00\u81F4\u3057\u305F\u969B\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u8A2D\u5B9A\u3059\u308B\u3053\u3068\u3067\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u69CB\u6210\u3057\u307E\u3059\u3002\n\n/set\n\t/set\u30B3\u30DE\u30F3\u30C9\u3068\u3057\u3066editor\u3001start\u304A\u3088\u3073feedback\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n\t\u524D\u8FF0\u306E\u3044\u305A\u308C\u304B\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3059\u308B\u306B\u306F\u3001set\u5024\u3092\u7701\u7565\u3057\u307E\u3059\u3002\n\n\u3053\u308C\u3089\u306E\u5F62\u5F0F\u306E\u8A73\u7D30\u306F\u3001\u5F62\u5F0F\u3092\u6307\u5B9A\u3057\u3066/help\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u4F8B:   /help /set format
 
 help.quest.summary = jshell\u306B\u95A2\u3059\u308B\u60C5\u5831\u3092\u53D6\u5F97\u3057\u307E\u3059
 help.quest.args = [<command>|<subject>]
@@ -229,28 +234,26 @@
 help.shortcuts.summary = \u30B7\u30E7\u30FC\u30C8\u30AB\u30C3\u30C8\u306E\u8AAC\u660E
 help.shortcuts =\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30B7\u30E7\u30FC\u30C8\u30AB\u30C3\u30C8\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\n<tab>\n\t\tJava\u8B58\u5225\u5B50\u3001jshell\u30B3\u30DE\u30F3\u30C9\u3001\u5834\u5408\u306B\u3088\u3063\u3066\u306F\n\t\tjshell\u30B3\u30DE\u30F3\u30C9\u5F15\u6570\u306E\u6700\u521D\u306E\u6570\u6587\u5B57\u3092\u5165\u529B\u3057\u305F\u5F8C\u306B\u3001\n\t\t<tab>\u30AD\u30FC\u3092\u62BC\u3059\u3068\u3001\u5165\u529B\u304C\u5B8C\u6210\u3057\u307E\u3059\u3002\n\t\t\u5B8C\u6210\u7D50\u679C\u304C\u8907\u6570\u3042\u308B\u5834\u5408\u3001\u4F7F\u7528\u53EF\u80FD\u306A\u5B8C\u6210\u7D50\u679C\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\nShift-<tab>\n\t\t\u30E1\u30BD\u30C3\u30C9\u307E\u305F\u306F\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u547C\u51FA\u3057\u306E\u540D\u524D\u3068\u5DE6\u4E38\u30AB\u30C3\u30B3\u306E\u5F8C\u306B\n\t\t<shift>\u30AD\u30FC\u3092\u62BC\u3057\u306A\u304C\u3089<tab>\u3092\u62BC\u3059\u3068\u3001\u4E00\u81F4\u3059\u308B\u3059\u3079\u3066\u306E\u30E1\u30BD\u30C3\u30C9/\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u306E\n\t\t\u30B7\u30CE\u30D7\u30B7\u30B9\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\n<fix-shortcut> v\n\t\t\u5B8C\u5168\u306A\u5F0F\u306E\u5F8C\u306B\u3001\u300C<fix-shortcut> v\u300D\u3092\u62BC\u3059\u3068\u3001\u5F0F\u306E\u30BF\u30A4\u30D7\u306B\u57FA\u3065\u3044\u305F\u30BF\u30A4\u30D7\u306E\n\t\t\u65B0\u3057\u3044\u5909\u6570\u304C\u5C0E\u5165\u3055\u308C\u307E\u3059\u3002\n\t\t\u300C<fix-shortcut>\u300D\u306F[Alt]+[F1]\u307E\u305F\u306F[Alt]+[Enter]\u3067\u3001\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306B\u3088\u3063\u3066\u7570\u306A\u308A\u307E\u3059\u3002\n\n<fix-shortcut> i\n\t\t\u89E3\u6C7A\u3067\u304D\u306A\u3044\u8B58\u5225\u5B50\u306E\u5F8C\u306B\u3001\u300C<fix-shortcut> i\u300D\u3092\u62BC\u3059\u3068\u3001jshell\u306F\u6307\u5B9A\u3057\u305F\n\t\t\u30AF\u30E9\u30B9\u30D1\u30B9\u306E\u5185\u5BB9\u306B\u57FA\u3065\u3044\u3066\u4F7F\u7528\u53EF\u80FD\u306A\u5B8C\u5168\u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u3092\u63D0\u793A\u3057\u307E\u3059\u3002\n\t\t\u300C<fix-shortcut>\u300D\u306F[Alt]+[F1]\u307E\u305F\u306F[Alt]+[Enter]\u3067\u3001\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306B\u3088\u3063\u3066\u7570\u306A\u308A\u307E\u3059\u3002
 
-help.set.format = \u30B9\u30CB\u30DA\u30C3\u30C8\u30FB\u30A4\u30D9\u30F3\u30C8\u3092\u30EC\u30DD\u30FC\u30C8\u3059\u308B\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n\t/set format <mode> <field> "<format>" <selector>...\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059 -- '/help /set mode'\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n<field>\u306F\u5B9A\u7FA9\u3059\u308B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u56FA\u6709\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u306E\u540D\u524D\u3067\u3059\u3002\n<format>\u306F\u5F15\u7528\u7B26\u306B\u56F2\u307E\u308C\u305F\u6587\u5B57\u5217\u3067\u3001\u6B21\u306E\u5834\u5408\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u5024\u3067\u3059: \n\u30BB\u30EC\u30AF\u30BF\u304C\u4E00\u81F4\u3059\u308B(\u307E\u305F\u306F\u30BB\u30EC\u30AF\u30BF\u304C\u306A\u3044)\u3002\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304C\u4F7F\u7528\u3055\u308C\u308B\u5834\u5408\u3001\n\u4E2D\u30AB\u30C3\u30B3\u3067\u56F2\u307E\u308C\u3066\u3044\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u540D\u304C\u305D\u306E\u3068\u304D\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u5024\u3067\u7F6E\u63DB\u3055\u308C\u307E\u3059\n\u3053\u308C\u3089\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306F\u3001\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u3067\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3082\u3001\n\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306B\u56FA\u6709\u306E\u3053\u308C\u3089\u306E\u4E8B\u524D\u5B9A\u7FA9\u6E08\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u3044\u305A\u308C\u304B\u3067\u3042\u308B\u5834\u5408\u3082\u3042\u308A\u307E\u3059:\n\t{name}       == \u540D\u524D\u3001\u4F8B: \u5909\u6570\u540D\u3001 ...\n\t{type}       == \u30BF\u30A4\u30D7\u540D\u3002\u5909\u6570\u307E\u305F\u306F\u5F0F\u306E\u30BF\u30A4\u30D7\u3001\n\t\t\t\u30E1\u30BD\u30C3\u30C9\u306E\u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\n\t{value}      == \u5F0F\u307E\u305F\u306F\u5909\u6570\u306E\u521D\u671F\u5316\u306E\u7D50\u679C\u5024\n\t{unresolved} == \u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306E\u30EA\u30B9\u30C8\n\t{errors}     == \u30EA\u30AB\u30D0\u30EA\u53EF\u80FD\u306A\u30A8\u30E9\u30FC\u306E\u30EA\u30B9\u30C8(\u51E6\u7406\u6642-\n\t\t\t"display"\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u307F)\n\t{err}        == \u672A\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u30FB\u30A8\u30E9\u30FC\u884C(\u51E6\u7406\u6642-\n\t\t\t"errorline"\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u307F)\n\u6B21\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306F\u30C4\u30FC\u30EB\u306B\u3088\u3063\u3066\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u3001\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u6C7A\u5B9A\u3057\u307E\u3059:\n\t{display}    == \u30B9\u30CB\u30DA\u30C3\u30C8\u30FB\u30A4\u30D9\u30F3\u30C8\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30E1\u30C3\u30BB\u30FC\u30B8\n\t{errorline}  == \u300Cerrors\u300D\u30D5\u30A3\u30FC\u30EB\u30C9\u5185\u306E\u30A8\u30E9\u30FC\u884C\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\n\t{pre}        == \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u63A5\u982D\u8F9E(\u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u958B\u59CB\u3059\u308B)\n\t{post}       == \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u63A5\u5C3E\u8F9E(\u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u7D42\u4E86\u3059\u308B)\n\t{errorpre}   == \u30A8\u30E9\u30FC\u63A5\u982D\u8F9E(\u30A8\u30E9\u30FC\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u958B\u59CB\u3059\u308B)\n\t{errorpost}  == \
-\u30A8\u30E9\u30FC\u63A5\u5C3E\u8F9E(\u30A8\u30E9\u30FC\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u7D42\u4E86\u3059\u308B)\n\u3053\u308C\u3089\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306B\u306F\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u8A2D\u5B9A\u304C\u3042\u308A\u307E\u3059(\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059)\u3002\n<selector>\u306F\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304C\u9069\u7528\u3055\u308C\u308B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u69CB\u9020\u306F\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306E\u30CF\u30A4\u30D5\u30F3\u533A\u5207\u308A\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\u30011\u3064\u306E\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306E\u5024\u306E\u30AB\u30F3\u30DE\u533A\u5207\u308A\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u306F\u5404\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\n\u3044\u305A\u308C\u304B\u306E\u5024\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\n\n\u30B1\u30FC\u30B9\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u7A2E\u985E\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\timport     -- \u30A4\u30F3\u30DD\u30FC\u30C8\u5BA3\u8A00\n\tclass      -- \u30AF\u30E9\u30B9\u5BA3\u8A00\n\tinterface  -- \u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u5BA3\u8A00\n\tenum       -- \u5217\u6319\u578B\u306E\u5BA3\u8A00\n\tannotation -- \u6CE8\u91C8\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u5BA3\u8A00\n\tmethod     -- \u30E1\u30BD\u30C3\u30C9\u5BA3\u8A00 -- \u6CE8\u610F: {type}==parameter-types\n\tvardecl    -- \u521D\u671F\u5316\u3057\u306A\u3044\u5909\u6570\u5BA3\u8A00\n\tvarinit    -- \u521D\u671F\u5316\u3059\u308B\u5909\u6570\u5BA3\u8A00\n\texpression -- \u5F0F -- \u6CE8\u610F: {name}==scratch-variable-name\n\tvarvalue   -- \u5909\u6570\u5024\u5F0F\n\tassignment -- \u5909\u6570\u3092\u5272\u308A\u5F53\u3066\u307E\u3059\n\tstatement  -- \u6587\n\u30A2\u30AF\u30B7\u30E7\u30F3\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306B\u767A\u751F\u3057\u305F\u5185\u5BB9\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tadded     -- \u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\n\tmodified  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u5909\u66F4\u3055\u308C\u307E\u3057\u305F\n\treplaced  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u65B0\u898F\u30B9\u30CB\u30DA\u30C3\u30C8\u3067\u7F6E\u63DB\u3055\u308C\u307E\u3057\u305F\n\toverwrote -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u307E\u3057\u305F\n\tdropped   -- \u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u524A\u9664\u3055\u308C\u307E\u3057\u305F\n\tused      -- \u4F7F\u7528\u3067\u304D\u306A\u3044\u3068\u304D\u306B\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u4F7F\u7528\u3055\u308C\u307E\u3057\u305F\n\u767A\u751F\u6642\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u3053\u308C\u304C\u76F4\u63A5\u307E\u305F\u306F\u9593\u63A5\u30A2\u30AF\u30B7\u30E7\u30F3\u3067\u3042\u308B\u304B\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tprimary -- \u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\n\tupdate  -- \u4F9D\u5B58\u30B9\u30CB\u30DA\u30C3\u30C8\u3078\u306E\u66F4\u65B0\n\u89E3\u6C7A\u72B6\u614B\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u89E3\u6C7A/\u5B9A\u7FA9\u306E\u72B6\u614B\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tok         -- \
-\u6B63\u3057\u304F\u89E3\u6C7A\u3055\u308C\u307E\u3057\u305F\n\tdefined    -- \u5FA9\u5143\u53EF\u80FD\u3067\u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306B\u3082\u304B\u304B\u308F\u3089\u305A\u5B9A\u7FA9\u3055\u308C\u307E\u3057\u305F\n\tnotdefined -- \u5FA9\u5143\u53EF\u80FD\u3067\u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306E\u305F\u3081\u5B9A\u7FA9\u3055\u308C\u307E\u305B\u3093\n\u672A\u89E3\u6C7A\u6570\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306E\u6570\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tunresolved0 -- \u672A\u89E3\u6C7A\u306E\u540D\u524D\u306F\u3042\u308A\u307E\u305B\u3093\n\tunresolved1 -- 1\u3064\u306E\u540D\u524D\u304C\u89E3\u6C7A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n\tunresolved2 -- 2\u3064\u4EE5\u4E0A\u306E\u540D\u524D\u304C\u89E3\u6C7A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n\u30A8\u30E9\u30FC\u6570\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30A8\u30E9\u30FC\u306E\u6570\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\terror0 -- \u30A8\u30E9\u30FC\u306A\u3057\n\terror1 -- 1\u3064\u306E\u30A8\u30E9\u30FC\n\terror2 -- 2\u3064\u4EE5\u4E0A\u306E\u30A8\u30E9\u30FC\n\n\u4F8B:\n\t/set format myformat action 'Created' added-primary\n\t/set format myformat action 'Update replaced' replaced-update\n\t/set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t/set format myformat display '{pre}{action} \u5909\u6570 {name}\u3001null\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F{post}' replaced-vardecl,varinit-ok-update\n\n\u30D5\u30A3\u30FC\u30EB\u30C9\u306B\u5BFE\u3059\u308B\u5F8C\u7D9A\u306E\u30BB\u30EC\u30AF\u30BF\u306B\u3088\u308A\u3001\u4EE5\u524D\u306B\u4F7F\u7528\u3055\u308C\u305F\u30BB\u30EC\u30AF\u30C8\u306E\u4E00\u90E8\u307E\u305F\u306F\u3059\u3079\u3066\u304C\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 -- \u6700\u5F8C\u306E\u30BB\u30EC\u30AF\u30BF\u304C\u6709\u52B9\u306B\u306A\u308A\u307E\u3059\n
-
-help.set.truncation = \u8868\u793A\u3055\u308C\u308B\u5024\u306E\u6700\u5927\u9577\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n\t/set truncation <mode> <length> <selector>...\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059 -- '/help /set mode'\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\n<length>\u306F\u6700\u5927\u9577\u3092\u8868\u3059\u7B26\u53F7\u306A\u3057\u6574\u6570\u3067\u3059\u3002\n<format>\u306F\u5F15\u7528\u7B26\u306B\u56F2\u307E\u308C\u305F\u6587\u5B57\u5217\u3067\u3001\u6B21\u306E\u5834\u5408\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u5024\u3067\u3059:\n<selector>\u306F\u3001\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306B\u3088\u3063\u3066\u5207\u6368\u3066\u9577\u306E\u5024\u3092\u5FAE\u8ABF\u6574\u3059\u308B\u5834\u5408\u306B\u306E\u307F\n\u5FC5\u8981\u3067\u3059\u3002<selector>\u306F\u3001\u5207\u6368\u3066\u304C\u9069\u7528\u3055\u308C\u308B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u69CB\u9020\u306F\u3001\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306E\u30CF\u30A4\u30D5\u30F3\u533A\u5207\u308A\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\u30011\u3064\u306E\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306E\u5024\u306E\u30AB\u30F3\u30DE\u533A\u5207\u308A\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u306F\u5404\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\n\u3044\u305A\u308C\u304B\u306E\u5024\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\n\n\u6B21\u306B\u793A\u3059\u306E\u306F\u3001\u5207\u6368\u3066\u306B\u95A2\u9023\u3059\u308B\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u3067\u3059\u3002\n\n\u30B1\u30FC\u30B9\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u7A2E\u985E\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tvardecl    -- \u521D\u671F\u5316\u3057\u306A\u3044\u5909\u6570\u5BA3\u8A00\n\tvarinit    -- \u521D\u671F\u5316\u3057\u306A\u3044\u5909\u6570\u5BA3\u8A00\n\texpression -- \u5F0F -- \u6CE8\u610F: {name}==scratch-variable-name\n\tvarvalue   -- \u5909\u6570\u5024\u5F0F\n\tassignment -- \u5909\u6570\u3092\u5272\u308A\u5F53\u3066\u307E\u3059\n\t\u30A2\u30AF\u30B7\u30E7\u30F3\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306B\u767A\u751F\u3057\u305F\u5185\u5BB9\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tadded     -- \u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\n\tmodified  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u5909\u66F4\u3055\u308C\u307E\u3057\u305F\n\treplaced  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u65B0\u898F\u30B9\u30CB\u30DA\u30C3\u30C8\u3067\u7F6E\u63DB\u3055\u308C\u307E\u3057\u305F\n\u4F8B:\n\t/set trunc mymode 80\n\t/set truncation mymode 45 expression\n\t/set truncation mymode 0 vardecl-modified,replaced\n\n\u30D5\u30A3\u30FC\u30EB\u30C9\u306B\u5BFE\u3059\u308B\u5F8C\u7D9A\u306E\u30BB\u30EC\u30AF\u30BF\u306B\u3088\u308A\u3001\u4EE5\u524D\u306B\u4F7F\u7528\u3055\u308C\u305F\u30BB\u30EC\u30AF\u30BF\u306E\u4E00\u90E8\u307E\u305F\u306F\u3059\u3079\u3066\u304C\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 -- \u6700\u5F8C\u306E\u30BB\u30EC\u30AF\u30BF\u304C\u6709\u52B9\u306B\u306A\u308A\u307E\u3059\n
+help.set._retain = '-retain'\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u3088\u308A\u3001\u5C06\u6765\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u4F7F\u7528\u3059\u308B\u305F\u3081\u306B\u8A2D\u5B9A\u3092\u4FDD\u5B58\u3057\u307E\u3059\u3002\n-retain\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u3001/set\u306E\u6B21\u306E\u5F62\u5F0F\u3067\u4F7F\u7528\u3067\u304D\u307E\u3059:\n\n\t/set editor -retain\n\t/set start -retain\n\t/set feedback -retain\n\t/set mode -retain\n\n\u8A73\u7D30\u306F\u3001\u3053\u308C\u3089\u306E\u30B3\u30DE\u30F3\u30C9\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044 -- \u4F8B: /help /set editor
 
-help.set.feedback = \u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u793A\u3059\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\n\n\t/set feedback <mode>\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n\u4E00\u610F\u306B\u3059\u308B\u305F\u3081\u306B\u5FC5\u8981\u306A\u6587\u5B57\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30E2\u30FC\u30C9\u306F\u8FFD\u52A0\u3067\u304D\u307E\u3059\u3002'/help /set mode'\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u73FE\u5728\u5B9A\u7FA9\u6E08\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9:\n
+help.set.format = \u30B9\u30CB\u30DA\u30C3\u30C8\u30FB\u30A4\u30D9\u30F3\u30C8\u3092\u30EC\u30DD\u30FC\u30C8\u3059\u308B\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059:\n\n\t/set format <mode> <field> "<format>" <selector>...\n\n\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059:\n\n\t/set format [<mode> [<field>]]\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059 -- '/help /set mode'\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n<field>\u306F\u5B9A\u7FA9\u3059\u308B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u56FA\u6709\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u306E\u540D\u524D\u3067\u3059\u3002\n<format>\u306F\u5F15\u7528\u7B26\u306B\u56F2\u307E\u308C\u305F\u6587\u5B57\u5217\u3067\u3001\u6B21\u306E\u5834\u5408\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u5024\u3067\u3059: \n\u30BB\u30EC\u30AF\u30BF\u304C\u4E00\u81F4\u3059\u308B(\u307E\u305F\u306F\u30BB\u30EC\u30AF\u30BF\u304C\u306A\u3044)\u3002\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304C\u4F7F\u7528\u3055\u308C\u308B\u5834\u5408\u3001\n\u4E2D\u30AB\u30C3\u30B3\u3067\u56F2\u307E\u308C\u3066\u3044\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u540D\u304C\u305D\u306E\u3068\u304D\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u5024\u3067\u7F6E\u63DB\u3055\u308C\u307E\u3059\n\u3053\u308C\u3089\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306F\u3001\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u3067\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3082\u3001\n\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306B\u56FA\u6709\u306E\u3053\u308C\u3089\u306E\u4E8B\u524D\u5B9A\u7FA9\u6E08\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u3044\u305A\u308C\u304B\u3067\u3042\u308B\u5834\u5408\u3082\u3042\u308A\u307E\u3059:\n\t{name}       == \u540D\u524D\u3001\u4F8B: \u5909\u6570\u540D\u3001 ...\n\t{type}       == \u30BF\u30A4\u30D7\u540D\u3002\u5909\u6570\u307E\u305F\u306F\u5F0F\u306E\u30BF\u30A4\u30D7\u3001\n\t\t\t\u30E1\u30BD\u30C3\u30C9\u306E\u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\n\t{value}      == \u5F0F\u307E\u305F\u306F\u5909\u6570\u306E\u521D\u671F\u5316\u306E\u7D50\u679C\u5024\n\t{unresolved} == \u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306E\u30EA\u30B9\u30C8\n\t{errors}     == \u30EA\u30AB\u30D0\u30EA\u53EF\u80FD\u306A\u30A8\u30E9\u30FC\u306E\u30EA\u30B9\u30C8(\u51E6\u7406\u6642-\n\t\t\t"display"\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u307F)\n\t{err}        == \u672A\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u30FB\u30A8\u30E9\u30FC\u884C(\u51E6\u7406\u6642-\n\t\t\t"errorline"\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u307F)\n\u6B21\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306F\u30C4\u30FC\u30EB\u306B\u3088\u3063\u3066\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u3001\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u6C7A\u5B9A\u3057\u307E\u3059:\n\t{display}    == \u30B9\u30CB\u30DA\u30C3\u30C8\u30FB\u30A4\u30D9\u30F3\u30C8\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30E1\u30C3\u30BB\u30FC\u30B8\n\t{errorline}  == \u300Cerrors\u300D\u30D5\u30A3\u30FC\u30EB\u30C9\u5185\u306E\u30A8\u30E9\u30FC\u884C\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\n\t{pre}        == \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u63A5\u982D\u8F9E(\u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u958B\u59CB\u3059\u308B)\n\t{post}       == \u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u63A5\u5C3E\u8F9E(\u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u7D42\u4E86\u3059\u308B)\n\t{errorpre}   == \u30A8\u30E9\u30FC\u63A5\u982D\u8F9E(\u30A8\u30E9\u30FC\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u958B\u59CB\u3059\u308B)\n\t{errorpost}  == \
+\u30A8\u30E9\u30FC\u63A5\u5C3E\u8F9E(\u30A8\u30E9\u30FC\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u7D42\u4E86\u3059\u308B)\n\u3053\u308C\u3089\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306B\u306F\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u8A2D\u5B9A\u304C\u3042\u308A\u307E\u3059(\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059)\u3002\n<selector>\u306F\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304C\u9069\u7528\u3055\u308C\u308B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u69CB\u9020\u306F\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306E\u30CF\u30A4\u30D5\u30F3\u533A\u5207\u308A\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\u30011\u3064\u306E\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306E\u5024\u306E\u30AB\u30F3\u30DE\u533A\u5207\u308A\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u306F\u5404\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\n\u3044\u305A\u308C\u304B\u306E\u5024\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\n\n\u30B1\u30FC\u30B9\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u7A2E\u985E\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\timport     -- \u30A4\u30F3\u30DD\u30FC\u30C8\u5BA3\u8A00\n\tclass      -- \u30AF\u30E9\u30B9\u5BA3\u8A00\n\tinterface  -- \u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u5BA3\u8A00\n\tenum       -- \u5217\u6319\u578B\u306E\u5BA3\u8A00\n\tannotation -- \u6CE8\u91C8\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u5BA3\u8A00\n\tmethod     -- \u30E1\u30BD\u30C3\u30C9\u5BA3\u8A00 -- \u6CE8\u610F: {type}==parameter-types\n\tvardecl    -- \u521D\u671F\u5316\u3057\u306A\u3044\u5909\u6570\u5BA3\u8A00\n\tvarinit    -- \u521D\u671F\u5316\u3059\u308B\u5909\u6570\u5BA3\u8A00\n\texpression -- \u5F0F -- \u6CE8\u610F: {name}==scratch-variable-name\n\tvarvalue   -- \u5909\u6570\u5024\u5F0F\n\tassignment -- \u5909\u6570\u3092\u5272\u308A\u5F53\u3066\u307E\u3059\n\tstatement  -- \u6587\n\u30A2\u30AF\u30B7\u30E7\u30F3\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306B\u767A\u751F\u3057\u305F\u5185\u5BB9\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tadded     -- \u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\n\tmodified  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u5909\u66F4\u3055\u308C\u307E\u3057\u305F\n\treplaced  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u65B0\u898F\u30B9\u30CB\u30DA\u30C3\u30C8\u3067\u7F6E\u63DB\u3055\u308C\u307E\u3057\u305F\n\toverwrote -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u307E\u3057\u305F\n\tdropped   -- \u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u524A\u9664\u3055\u308C\u307E\u3057\u305F\n\tused      -- \u4F7F\u7528\u3067\u304D\u306A\u3044\u3068\u304D\u306B\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u4F7F\u7528\u3055\u308C\u307E\u3057\u305F\n\u767A\u751F\u6642\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u3053\u308C\u304C\u76F4\u63A5\u307E\u305F\u306F\u9593\u63A5\u30A2\u30AF\u30B7\u30E7\u30F3\u3067\u3042\u308B\u304B\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tprimary -- \u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\n\tupdate  -- \u4F9D\u5B58\u30B9\u30CB\u30DA\u30C3\u30C8\u3078\u306E\u66F4\u65B0\n\u89E3\u6C7A\u72B6\u614B\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u89E3\u6C7A/\u5B9A\u7FA9\u306E\u72B6\u614B\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tok         -- \
+\u6B63\u3057\u304F\u89E3\u6C7A\u3055\u308C\u307E\u3057\u305F\n\tdefined    -- \u5FA9\u5143\u53EF\u80FD\u3067\u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306B\u3082\u304B\u304B\u308F\u3089\u305A\u5B9A\u7FA9\u3055\u308C\u307E\u3057\u305F\n\tnotdefined -- \u5FA9\u5143\u53EF\u80FD\u3067\u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306E\u305F\u3081\u5B9A\u7FA9\u3055\u308C\u307E\u305B\u3093\n\u672A\u89E3\u6C7A\u6570\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u672A\u89E3\u6C7A\u306E\u53C2\u7167\u306E\u6570\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tunresolved0 -- \u672A\u89E3\u6C7A\u306E\u540D\u524D\u306F\u3042\u308A\u307E\u305B\u3093\n\tunresolved1 -- 1\u3064\u306E\u540D\u524D\u304C\u89E3\u6C7A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n\tunresolved2 -- 2\u3064\u4EE5\u4E0A\u306E\u540D\u524D\u304C\u89E3\u6C7A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n\u30A8\u30E9\u30FC\u6570\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30A8\u30E9\u30FC\u306E\u6570\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\terror0 -- \u30A8\u30E9\u30FC\u306A\u3057\n\terror1 -- 1\u3064\u306E\u30A8\u30E9\u30FC\n\terror2 -- 2\u3064\u4EE5\u4E0A\u306E\u30A8\u30E9\u30FC\n\n\u4F8B:\n\t/set format myformat action 'Created' added-primary\n\t/set format myformat action 'Update replaced' replaced-update\n\t/set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t/set format myformat display '{pre}{action} \u5909\u6570 {name}\u3001null\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F{post}' replaced-vardecl,varinit-ok-update\n\n\u30D5\u30A3\u30FC\u30EB\u30C9\u306B\u5BFE\u3059\u308B\u5F8C\u7D9A\u306E\u30BB\u30EC\u30AF\u30BF\u306B\u3088\u308A\u3001\u4EE5\u524D\u306B\u4F7F\u7528\u3055\u308C\u305F\u30BB\u30EC\u30AF\u30C8\u306E\u4E00\u90E8\u307E\u305F\u306F\u3059\u3079\u3066\u304C\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 -- \u6700\u5F8C\u306E\u30BB\u30EC\u30AF\u30BF\u304C\u6709\u52B9\u306B\u306A\u308A\u307E\u3059\n\n<format>\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u73FE\u5728\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n<mode>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u305D\u306E\u30E2\u30FC\u30C9\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u8A2D\u5B9A\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n<mode>\u3068<field>\u306E\u4E21\u65B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\n\u305D\u306E\u30E2\u30FC\u30C9\u304A\u3088\u3073\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u8A2D\u5B9A\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u4F8B:\n\t/set format myformat\n\u30E2\u30FC\u30C9myformat\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\n
 
-help.set.mode = \u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002\u5FC5\u8981\u306B\u5FDC\u3058\u3066\u65E2\u5B58\u306E\u30E2\u30FC\u30C9\u304B\u3089\u30B3\u30D4\u30FC\u3057\u307E\u3059\u3002\n\n\t/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\n<new-mode>\u306F\u4F5C\u6210\u3059\u308B\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<old-mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<old-mode>\u304C\u3042\u308B\u5834\u5408\u3001\u305D\u306E\u8A2D\u5B9A\u304C\u65B0\u898F\u30E2\u30FC\u30C9\u306B\u30B3\u30D4\u30FC\u3055\u308C\u307E\u3059\u3002\n'-command'\u307E\u305F\u306F'-quiet'\u306B\u3088\u308A\u3001\u60C5\u5831/\u691C\u8A3C\u4E2D\u306E\u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u8868\u793A\u3059\u308B\u304B\u3069\u3046\u304B\u304C\u6C7A\u5B9A\u3057\u307E\u3059\u3002\n\n\u65B0\u898F\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u3057\u305F\u3089\u3001'/set format'\u304A\u3088\u3073'/set prompt'\u3092\u4F7F\u7528\u3057\u3066\u69CB\u6210\u3057\u307E\u3059\u3002\n\u65B0\u898F\u30E2\u30FC\u30C9\u3092\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001'/set feedback'\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\n
-help.set.prompt = \u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u6A19\u6E96\u30D7\u30ED\u30F3\u30D7\u30C8\u3068\u7D9A\u884C\u30D7\u30ED\u30F3\u30D7\u30C8\u306E\u4E21\u65B9\u3092\u8A2D\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<prompt>\u304A\u3088\u3073<continuation-prompt>\u306F\u5165\u529B\u30D7\u30ED\u30F3\u30D7\u30C8\u3068\u3057\u3066\u51FA\u529B\u3055\u308C\u308B\u5F15\u7528\u7B26\u3067\u56F2\u307E\u308C\u305F\u6587\u5B57\u5217\u3067\u3059\u3002\n\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3001\u4E21\u65B9\u3068\u3082\u3001\u6B21\u306E\u30B9\u30CB\u30DA\u30C3\u30C8ID\u3067\u7F6E\u304D\u63DB\u3048\u3089\u308C\u308B'%s'\u3092\u542B\u3080\u3053\u3068\u304C\u3067\u304D\u307E\u3059 --\n\u5165\u529B\u3057\u305F\u5185\u5BB9\u304C\u305D\u306EID\u306B\u5272\u308A\u5F53\u3066\u3089\u308C\u306A\u3044\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\u305F\u3068\u3048\u3070\u3001\u30A8\u30E9\u30FC\u307E\u305F\u306F\u30B3\u30DE\u30F3\u30C9\u3067\u3042\u308B\u5834\u5408\u306A\u3069\u3067\u3059\u3002\n\u7D9A\u884C\u30D7\u30ED\u30F3\u30D7\u30C8\u306F\u8907\u6570\u884C\u30B9\u30CB\u30DA\u30C3\u30C8\u306E2\u884C\u76EE\u4EE5\u964D\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n
+help.set.truncation = \u8868\u793A\u3055\u308C\u308B\u5024\u306E\u6700\u5927\u9577\u3092\u8A2D\u5B9A\u3057\u307E\u3059:\n\n\t/set truncation <mode> <length> <selector>...\n\n\u73FE\u5728\u306E\u5207\u6368\u3066\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059:\n\n\t/set truncation [<mode>]\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059 -- '/help /set mode'\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n<length>\u306F\u6700\u5927\u9577\u3092\u8868\u3059\u7B26\u53F7\u306A\u3057\u6574\u6570\u3067\u3059\u3002\n<selector>\u306F\u3001\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306B\u3088\u3063\u3066\u5207\u6368\u3066\u9577\u306E\u5024\u3092\u5FAE\u8ABF\u6574\u3059\u308B\u5834\u5408\u306B\u306E\u307F\n\u5FC5\u8981\u3067\u3059\u3002<selector>\u306F\u3001\u5207\u6368\u3066\u304C\u9069\u7528\u3055\u308C\u308B\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u69CB\u9020\u306F\u3001\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306E\u30CF\u30A4\u30D5\u30F3\u533A\u5207\u308A\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\u30011\u3064\u306E\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306E\u5024\u306E\u30AB\u30F3\u30DE\u533A\u5207\u308A\u306E\u30EA\u30B9\u30C8\u3067\u3059\u3002\n\u30BB\u30EC\u30AF\u30BF\u306F\u5404\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u30EA\u30B9\u30C8\u306F\n\u3044\u305A\u308C\u304B\u306E\u5024\u304C\u4E00\u81F4\u3059\u308C\u3070\u4E00\u81F4\u3068\u306A\u308A\u307E\u3059\u3002\n\n\u6B21\u306B\u793A\u3059\u306E\u306F\u3001\u5207\u6368\u3066\u306B\u95A2\u9023\u3059\u308B\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u3067\u3059\u3002\n\n\u30B1\u30FC\u30B9\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u7A2E\u985E\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tvardecl    -- \u521D\u671F\u5316\u3057\u306A\u3044\u5909\u6570\u5BA3\u8A00\n\tvarinit    -- \u521D\u671F\u5316\u3059\u308B\u5909\u6570\u5BA3\u8A00\n\texpression -- \u5F0F -- \u6CE8\u610F: {name}==scratch-variable-name\n\tvarvalue   -- \u5909\u6570\u5024\u5F0F\n\tassignment -- \u5909\u6570\u3092\u5272\u308A\u5F53\u3066\u307E\u3059\n\t\u30A2\u30AF\u30B7\u30E7\u30F3\u30FB\u30BB\u30EC\u30AF\u30BF\u7A2E\u985E\u306F\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306B\u767A\u751F\u3057\u305F\u5185\u5BB9\u3092\u793A\u3057\u307E\u3059\u3002\u5024\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\tadded     -- \u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\n\tmodified  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u5909\u66F4\u3055\u308C\u307E\u3057\u305F\n\treplaced  -- \u65E2\u5B58\u306E\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\u65B0\u898F\u30B9\u30CB\u30DA\u30C3\u30C8\u3067\u7F6E\u63DB\u3055\u308C\u307E\u3057\u305F\n\u4F8B:\n\t/set trunc mymode 80\n\t/set truncation mymode 45 expression\n\t/set truncation mymode 0 vardecl-modified,replaced\n\n\u30D5\u30A3\u30FC\u30EB\u30C9\u306B\u5BFE\u3059\u308B\u5F8C\u7D9A\u306E\u30BB\u30EC\u30AF\u30BF\u306B\u3088\u308A\u3001\u4EE5\u524D\u306B\u4F7F\u7528\u3055\u308C\u305F\u30BB\u30EC\u30AF\u30BF\u306E\u4E00\u90E8\u307E\u305F\u306F\u3059\u3079\u3066\u304C\u4E0A\u66F8\u304D\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 -- \u6700\u5F8C\u306E\u30BB\u30EC\u30AF\u30BF\u304C\u6709\u52B9\u306B\u306A\u308A\u307E\u3059\n\n<length>\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u5207\u6368\u3066\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n<mode>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u305D\u306E\u30E2\u30FC\u30C9\u306E\u5207\u6368\u3066\u8A2D\u5B9A\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\u4F8B:\n\t/set truncation \
+myformat\n\u30E2\u30FC\u30C9myformat\u306E\u5207\u6368\u3066\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\n
 
-help.set.editor =/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\n\n\t/set editor <command>|-default\n\n<command>\u306F\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u4F9D\u5B58\u6587\u5B57\u5217\u3067\u3059\u3002\n<command>\u306B\u306F\u30B9\u30DA\u30FC\u30B9\u3067\u533A\u5207\u3089\u308C\u305F\u5F15\u6570(\u30D5\u30E9\u30B0\u306A\u3069)\u304C\u542B\u307E\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\n/edit\u3092\u4F7F\u7528\u3059\u308B\u969B\u306B\u3001\u7DE8\u96C6\u3059\u308B\u4E00\u6642\u30D5\u30A1\u30A4\u30EB\u304C\u6700\u5F8C\u306E\u5F15\u6570\u3068\u3057\u3066\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002\n\u304B\u308F\u308A\u306B-default\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u7D44\u8FBC\u307F\u30A8\u30C7\u30A3\u30BF\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002
+help.set.feedback = \u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u793A\u3059\u3001\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u8A2D\u5B9A\u3057\u307E\u3059:\n\n\t/set feedback [-retain] <mode>\n\n\u5C06\u6765\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u305F\u3081\u306B\u73FE\u5728\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4FDD\u6301\u3057\u307E\u3059:\n\n\t/set feedback -retain\n\n\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u8868\u793A\u3057\u3001\u4F7F\u7528\u53EF\u80FD\u306A\u30E2\u30FC\u30C9\u3092\u30EA\u30B9\u30C8\u3057\u307E\u3059:\n\n\t/set feedback\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n\u4E00\u610F\u306B\u3059\u308B\u305F\u3081\u306B\u5FC5\u8981\u306A\u6587\u5B57\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30E2\u30FC\u30C9\u306F\u8FFD\u52A0\u3067\u304D\u307E\u3059\u3002'/help /set mode'\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\n\n-retain\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u8A2D\u5B9A\u306Fjshell\u30C4\u30FC\u30EB\u306E\u3053\u306E\u5B9F\u884C\u3068\u5C06\u6765\u306E\n\u5B9F\u884C\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n<mode>\u307E\u305F\u306F-retain\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u73FE\u5728\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u304A\u3088\u3073\u4F7F\u7528\u53EF\u80FD\u306A\u30E2\u30FC\u30C9\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n
 
-help.set.start =\u8D77\u52D5\u69CB\u6210\u3092\u8A2D\u5B9A\u3057\u307E\u3059 -- \u8D77\u52D5\u6642\u306B\u8AAD\u307F\u53D6\u3089\u308C\u308B\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u3002\n\n\t/set start <file>|-default|-none\n\n\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067/reset\u307E\u305F\u306F/reload\u30B3\u30DE\u30F3\u304C\u4F7F\u7528\u3055\u308C\u308B\u5834\u5408\u3001\n\u6307\u5B9A\u3057\u305F<file>\u306E\u5185\u5BB9\u304C\u3001\u4F7F\u7528\u3055\u308C\u308B\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u306A\u308A\u307E\u3059\u3002\n\u304B\u308F\u308A\u306B-default\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\n\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n-none\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3059\u308B\u3068\u3001\u8D77\u52D5\u304C\u7A7A\u306B\u306A\u308A\u307E\u3059 -- \u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u307E\u305F\u306F\n\u30B3\u30DE\u30F3\u30C9\u304C\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\n\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u306F\u8D77\u52D5\u8A2D\u5B9A\u3092\u30C6\u30B9\u30C8\u3059\u308B\u306E\u306B\u6709\u52B9\u3067\u3059\u3002jshell\u30C4\u30FC\u30EB\u306E\u4ECA\u5F8C\u306E\u5B9F\u884C\u306E\u305F\u3081\u306B\n\u305D\u308C\u3089\u3092\u4FDD\u6301\u3059\u308B\u306B\u306F\u3001\u6B21\u306E\u30B3\u30DE\u30F3\u30C9\u3092\u4F7F\u7528\u3057\u307E\u3059:\n\t/retain start\n
+help.set.mode = \u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002\u5FC5\u8981\u306B\u5FDC\u3058\u3066\u65E2\u5B58\u306E\u30E2\u30FC\u30C9\u304B\u3089\u30B3\u30D4\u30FC\u3057\u307E\u3059:\n\n\t/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\u5C06\u6765\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u305F\u3081\u306B\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4FDD\u6301\u3057\u307E\u3059:\n\n\t/set mode -retain <mode>\n\n\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u524A\u9664\u3057\u307E\u3059:\n\n\t/set mode -delete [-retain] <mode>\n\n\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059:\n\n\t/set mode [<mode>]\n\n<new-mode>\u306F\u4F5C\u6210\u3059\u308B\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<old-mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<old-mode>\u304C\u3042\u308B\u5834\u5408\u3001\u305D\u306E\u8A2D\u5B9A\u304C\u65B0\u898F\u30E2\u30FC\u30C9\u306B\u30B3\u30D4\u30FC\u3055\u308C\u307E\u3059\u3002\n'-command'\u307E\u305F\u306F'-quiet'\u306B\u3088\u308A\u3001\u60C5\u5831/\u691C\u8A3C\u4E2D\u306E\u30B3\u30DE\u30F3\u30C9\u30FB\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u8868\u793A\u3059\u308B\u304B\u3069\u3046\u304B\u304C\u6C7A\u5B9A\u3057\u307E\u3059\u3002\n\n\u65B0\u898F\u30E2\u30FC\u30C9\u3092\u4F5C\u6210\u3057\u305F\u3089\u3001'/set format'\u3001'/set prompt'\u304A\u3088\u3073'/set truncation'\u3092\u4F7F\u7528\u3057\u3066\n\u69CB\u6210\u3057\u307E\u3059\u3002\u65B0\u898F\u30E2\u30FC\u30C9\u3092\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001'/set feedback'\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\n\n-retain\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u30E2\u30FC\u30C9(\u305D\u306E\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306E\u30D7\u30ED\u30F3\u30D7\u30C8\u3001\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304A\u3088\u3073\u5207\u6368\u3066\u8A2D\u5B9A\u3092\u542B\u3080)\u306F\u3001\njshell\u30C4\u30FC\u30EB\u306E\u3053\u306E\u5B9F\u884C\u3068\u5C06\u6765\u306E\u5B9F\u884C\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n-retain\u3068-delete\u306E\u4E21\u65B9\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u30E2\u30FC\u30C9\u306F\u73FE\u5728\u304A\u3088\u3073\u5C06\u6765\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u304B\u3089\n\u524A\u9664\u3055\u308C\u307E\u3059\u3002\n\n\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u30E2\u30FC\u30C9\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n<mode>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u305D\u306E\u30E2\u30FC\u30C9\u306E\u30E2\u30FC\u30C9\u8A2D\u5B9A\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\u6CE8\u610F: \u30E2\u30FC\u30C9\u306E\u8A2D\u5B9A\u306B\u306F\u3001\u30D7\u30ED\u30F3\u30D7\u30C8\u3001\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304A\u3088\u3073\u5207\u6368\u3066\u306E\u8A2D\u5B9A\u304C\u542B\u307E\u308C\u308B\u305F\u3081\u3001\n\u3053\u308C\u3089\u3082\u540C\u69D8\u306B\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\u4F8B:\n\t/set mode myformat\n\u30E2\u30FC\u30C9myformat\u306E\u30E2\u30FC\u30C9\u3001\u30D7\u30ED\u30F3\u30D7\u30C8\u3001\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u304A\u3088\u3073\u5207\u6368\u3066\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\n
 
-help.retain.feedback = \u5165\u529B\u3057\u305F\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u5BFE\u3057\u3066\u8868\u793A\u3055\u308C\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u306B\u4F7F\u7528\u3059\u308B\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u3092\u4FDD\u6301\u3057\u307E\u3059\u3002\n\u3053\u306E\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306F\u73FE\u5728\u304A\u3088\u3073\u4ECA\u5F8C\u306Ejshell\u30C4\u30FC\u30EB\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n\t/retain feedback [<mode>]\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n\u4E00\u610F\u306B\u3059\u308B\u305F\u3081\u306B\u5FC5\u8981\u306A\u6587\u5B57\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002\n<mode>\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u306F\u73FE\u5728\u306E\u30E2\u30FC\u30C9(\u6700\u65B0\u306E/set feedback\u307E\u305F\u306F/retain feedback\n\u30B3\u30DE\u30F3\u30C9\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u3068\u304A\u308A)\u3092\u4FDD\u6301\u3057\u307E\u3059:\n
-help.retain.mode = \u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u5B58\u5728\u304A\u3088\u3073\u69CB\u6210\u3092\u4FDD\u6301\u3057\u307E\u3059\u3002\n\u3053\u306E\u30E2\u30FC\u30C9\u306F\u73FE\u5728\u304A\u3088\u3073\u4ECA\u5F8C\u306Ejshell\u30C4\u30FC\u30EB\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u4F7F\u7528\u53EF\u80FD\u3067\u3059\u3002
-\n\t/retain mode <mode>\n\n<mode>\u306F\u4FDD\u6301\u3059\u308B\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<mode>\u306F\u4E8B\u524D\u306B/set mode\u3067\u4F5C\u6210\u3057\u3001\u5FC5\u8981\u306B\u5FDC\u3058\u3066\n/set prompt\u3001/set format\u304A\u3088\u3073/set truncation\u3067\u69CB\u6210\u3057\u3066\u304A\u304F\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n
+help.set.prompt = \u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u6A19\u6E96\u30D7\u30ED\u30F3\u30D7\u30C8\u3068\u7D9A\u884C\u30D7\u30ED\u30F3\u30D7\u30C8\u306E\u4E21\u65B9\u3092\u8A2D\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059:\n\n\t/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\n\u6A19\u6E96\u30D7\u30ED\u30F3\u30D7\u30C8\u3068\u7D9A\u884C\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8868\u793A\u3057\u307E\u3059:\n\n\t/set prompt [<mode>]\n\n<mode>\u306F\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u30FB\u30E2\u30FC\u30C9\u306E\u540D\u524D\u3067\u3059\u3002\n<prompt>\u304A\u3088\u3073<continuation-prompt>\u306F\u5165\u529B\u30D7\u30ED\u30F3\u30D7\u30C8\u3068\u3057\u3066\u51FA\u529B\u3055\u308C\u308B\u5F15\u7528\u7B26\u3067\u56F2\u307E\u308C\u305F\u6587\u5B57\u5217\u3067\u3059\u3002\n\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3001\u4E21\u65B9\u3068\u3082\u3001\u6B21\u306E\u30B9\u30CB\u30DA\u30C3\u30C8ID\u3067\u7F6E\u304D\u63DB\u3048\u3089\u308C\u308B'%s'\u3092\u542B\u3080\u3053\u3068\u304C\u3067\u304D\u307E\u3059 --\n\u5165\u529B\u3057\u305F\u5185\u5BB9\u304C\u305D\u306EID\u306B\u5272\u308A\u5F53\u3066\u3089\u308C\u306A\u3044\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\u305F\u3068\u3048\u3070\u3001\u30A8\u30E9\u30FC\u307E\u305F\u306F\u30B3\u30DE\u30F3\u30C9\u3067\u3042\u308B\u5834\u5408\u306A\u3069\u3067\u3059\u3002\n\u7D9A\u884C\u30D7\u30ED\u30F3\u30D7\u30C8\u306F\u8907\u6570\u884C\u30B9\u30CB\u30DA\u30C3\u30C8\u306E2\u884C\u76EE\u4EE5\u964D\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n<prompt>\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u73FE\u5728\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n<mode>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u305D\u306E\u30E2\u30FC\u30C9\u306E\u30D7\u30ED\u30F3\u30D7\u30C8\u306E\u307F\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\u4F8B:\n\t/set prompt myformat\n\u30E2\u30FC\u30C9myformat\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u30D7\u30ED\u30F3\u30D7\u30C8\u3092\u8868\u793A\u3057\u307E\u3059\n
 
-help.retain.editor =/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u4FDD\u6301\u3057\u307E\u3059\u3002\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u306F\u3001\u73FE\u5728\u304A\u3088\u3073\u4ECA\u5F8C\u306E\njshell\u30C4\u30FC\u30EB\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067/edit\u30B3\u30DE\u30F3\u30C9\u3092\u4F7F\u7528\u3059\u308B\u969B\u306B\u8D77\u52D5\u3055\u308C\u307E\u3059\u3002\n\n\t/retain editor <command>|-default\n\n<command>\u306F\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u4F9D\u5B58\u6587\u5B57\u5217\u3067\u3059\u3002\n<command>\u306B\u306F\u30B9\u30DA\u30FC\u30B9\u3067\u533A\u5207\u3089\u308C\u305F\u5F15\u6570(\u30D5\u30E9\u30B0\u306A\u3069)\u304C\u542B\u307E\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\n/edit\u3092\u4F7F\u7528\u3059\u308B\u969B\u306B\u3001\u7DE8\u96C6\u3059\u308B\u4E00\u6642\u30D5\u30A1\u30A4\u30EB\u304C\u6700\u5F8C\u306E\u5F15\u6570\u3068\u3057\u3066\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002\n\u304B\u308F\u308A\u306B-default\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u7D44\u8FBC\u307F\u30A8\u30C7\u30A3\u30BF\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\u4F55\u3082\u6307\u5B9A\u3057\u306A\u3044\u3068\u3001\u6700\u5F8C\u306E/set editor\u307E\u305F\u306F/retain editor\u30B3\u30DE\u30F3\u30C9\u3067\u8A2D\u5B9A\u3055\u308C\u305F\n\u30A8\u30C7\u30A3\u30BF\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\u30A8\u30C7\u30A3\u30BF\u306F\u4FDD\u6301\u3055\u308C\u3001\u73FE\u5728\u304A\u3088\u3073\u4ECA\u5F8C\u306Ejshell\u30C4\u30FC\u30EB\u306E\u5B9F\u884C\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002
+help.set.editor =/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u6307\u5B9A\u3057\u307E\u3059:\n\n\t/set editor [-retain] [-wait] <command>\n\n\t/set editor [-retain] -default\n\n\t/set editor [-retain] -delete\n\n\u5C06\u6765\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u305F\u3081\u306B\u73FE\u5728\u306E\u30A8\u30C7\u30A3\u30BF\u8A2D\u5B9A\u3092\u4FDD\u6301\u3057\u307E\u3059:\n\n\t/set editor -retain\n\n/edit\u30B3\u30DE\u30F3\u30C9\u3067\u8D77\u52D5\u3059\u308B\u30B3\u30DE\u30F3\u30C9\u3092\u8868\u793A\u3057\u307E\u3059:\n\n\t/set editor\n\n<command>\u306F\u30AA\u30DA\u30EC\u30FC\u30C6\u30A3\u30F3\u30B0\u30FB\u30B7\u30B9\u30C6\u30E0\u4F9D\u5B58\u6587\u5B57\u5217\u3067\u3059\u3002\n<command>\u306B\u306F\u30B9\u30DA\u30FC\u30B9\u3067\u533A\u5207\u3089\u308C\u305F\u5F15\u6570(\u30D5\u30E9\u30B0\u306A\u3069)\u304C\u542B\u307E\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\n\n-default\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u7D44\u8FBC\u307F\u30A8\u30C7\u30A3\u30BF\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n-delete\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u4EE5\u524D\u306E\u8A2D\u5B9A\u306F\u7121\u8996\u3055\u308C\u307E\u3059 -- \u30A8\u30C7\u30A3\u30BF\n\u8A2D\u5B9A\u306F\u3001jshell\u30C4\u30FC\u30EB\u306E\u8D77\u52D5\u6642\u306B\u521D\u671F\u5316\u3055\u308C\u307E\u3059\u3002\u5177\u4F53\u7684\u306B\u306F\u3001\u4FDD\u6301\u3055\u308C\u305F\u8A2D\u5B9A\u304C\n\u5B58\u5728\u3059\u308B\u5834\u5408\u3001(\u4FDD\u6301\u3055\u308C\u305F\u8A2D\u5B9A\u3092\u524A\u9664\u3059\u308B-retain\u3068-delete\u306E\u4E21\u65B9\u304C\u6307\u5B9A\u3055\u308C\u3066\n\u3044\u306A\u3051\u308C\u3070)\u305D\u308C\u304C\u4F7F\u7528\u3055\u308C\u3001\u6B21\u306E\u74B0\u5883\u5909\u6570\u306E\u3044\u305A\u308C\u304B\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\n\u305D\u308C\u304C(\u305D\u306E\u9806\u5E8F\u3067)\u4F7F\u7528\u3055\u308C\u307E\u3059: JSHELLEDITOR\u3001VISUAL\u307E\u305F\u306FEDITOR\u3002\n\u305D\u308C\u4EE5\u5916\u306E\u5834\u5408\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u7D44\u8FBC\u307F\u30A8\u30C7\u30A3\u30BF\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n<command>\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u305D\u308C\u304C\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u3068\u3057\u3066\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002<command>\u306F\u3001\n\u30D7\u30ED\u30B0\u30E9\u30E0\u3068\u30BC\u30ED\u500B\u4EE5\u4E0A\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u5F15\u6570\u3067\u69CB\u6210\u3055\u308C\u307E\u3059\u3002<command>\u304C\u4F7F\u7528\u3055\u308C\u308B\u5834\u5408\u3001\n\u7DE8\u96C6\u5BFE\u8C61\u306E\u4E00\u6642\u30D5\u30A1\u30A4\u30EB\u304C\u6700\u5F8C\u306E\u5F15\u6570\u3068\u3057\u3066\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002\n\u901A\u5E38\u3001\u7DE8\u96C6\u30E2\u30FC\u30C9\u306F\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u304C\u7D42\u4E86\u3059\u308B\u307E\u3067\u7D99\u7D9A\u3057\u307E\u3059\u3002\u4E00\u90E8\u306E\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u306F\u3001\n\u305F\u3068\u3048\u3070\u7DE8\u96C6\u30A6\u30A3\u30F3\u30C9\u30A6\u304C\u7D42\u4E86\u3059\u308B\u3068\u5373\u5EA7\u306B\u7D42\u4E86\u3059\u308B\u305F\u3081\u3001\u5916\u90E8\u30A8\u30C7\u30A3\u30BF\u30FB\u30D5\u30E9\u30B0\u3092\u4F7F\u7528\u3057\u3066\n\u5373\u6642\u306E\u7D42\u4E86\u3092\u56DE\u907F\u3059\u308B\u304B\u3001-wait\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u3001\u7DE8\u96C6\u30E2\u30FC\u30C9\u304C\u7D42\u4E86\u3059\u308B\u30BF\u30A4\u30DF\u30F3\u30B0\u3092\n\u6307\u5B9A\u3059\u308B\u3088\u3046\u30E6\u30FC\u30B6\u30FC\u306B\u8981\u6C42\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u6CE8\u610F: \
+\u7DE8\u96C6\u30E2\u30FC\u30C9\u4E2D\u3001\u30B3\u30DE\u30F3\u30C9\u5165\u529B\u306F\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3002\u7DE8\u96C6\u30E2\u30FC\u30C9\u306E\u7D42\u4E86\u5F8C\u3001\u7DE8\u96C6\u3055\u308C\u305F\n\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u5909\u66F4\u5185\u5BB9\u306F\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3002\n\n-retain\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u8A2D\u5B9A\u306Fjshell\u30C4\u30FC\u30EB\u306E\u3053\u306E\u5B9F\u884C\u3068\u5C06\u6765\u306E\n\u5B9F\u884C\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n<command>\u307E\u305F\u306F\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u30A8\u30C7\u30A3\u30BF\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n
 
-help.retain.start =\u8D77\u52D5\u69CB\u6210\u3092\u8A2D\u5B9A\u3057\u307E\u3059 -- \u8D77\u52D5\u6642\u306B\u8AAD\u307F\u53D6\u3089\u308C\u308B\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306E\n\u30B7\u30FC\u30B1\u30F3\u30B9\u3002\n\n\t/retain start [<file>|-default|-none]\n\n<file>\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u6307\u5B9A\u3057\u305F<file>\u306E\u5185\u5BB9\u304C\n\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\n\u306A\u308A\u307E\u3059\u3002\n\u304B\u308F\u308A\u306B-default\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\n\u8D77\u52D5\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n-none\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3059\u308B\u3068\u3001\u8D77\u52D5\u304C\u7A7A\u306B\u306A\u308A\u307E\u3059 -- \u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u307E\u305F\u306F\n\u30B3\u30DE\u30F3\u30C9\u304C\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\n\u3053\u308C\u3089\u3092\u4F55\u3082\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u8D77\u52D5\u306F'/set start''\u307E\u305F\u306F''/retain start'\u30B3\u30DE\u30F3\u30C9\u3067\n\u6700\u5F8C\u306B\u6307\u5B9A\u3055\u308C\u305F\u3082\u306E\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\u8D77\u52D5\u306F\u4FDD\u6301\u3055\u308C\u3001jshell\u30C4\u30FC\u30EB\u304C\u8D77\u52D5\u307E\u305F\u306F\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u305F\u3068\u304D\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059
+help.set.start =\u8D77\u52D5\u69CB\u6210\u3092\u8A2D\u5B9A\u3057\u307E\u3059 -- \u8D77\u52D5\u6642\u306B\u8AAD\u307F\u53D6\u3089\u308C\u308B\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306E\u30B7\u30FC\u30B1\u30F3\u30B9:\n\n\t/set start [-retain] <file>\n\n\t/set start [-retain] -default\n\n\t/set start [-retain] -none\n\n\u5C06\u6765\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u305F\u3081\u306B\u8D77\u52D5\u69CB\u6210\u3092\u4FDD\u6301\u3057\u307E\u3059:\n\n\t/set start -retain\n\n\u8D77\u52D5\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059:\n\n\t/set start\n\n\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067/reset\u307E\u305F\u306F/reload\u30B3\u30DE\u30F3\u30C9\u304C\u4F7F\u7528\u3055\u308C\u308B\u5834\u5408\u3001\n\u6307\u5B9A\u3057\u305F<file>\u306E\u5185\u5BB9\u304C\u3001\u4F7F\u7528\u3055\u308C\u308B\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304A\u3088\u3073\u30B3\u30DE\u30F3\u30C9\u306B\u306A\u308A\u307E\u3059\u3002\n\u304B\u308F\u308A\u306B-default\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u4E8B\u524D\u306B\u5B9A\u7FA9\u3055\u308C\u305F\u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u304C\n\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n-none\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3059\u308B\u3068\u3001\u8D77\u52D5\u304C\u7A7A\u306B\u306A\u308A\u307E\u3059 -- \u8D77\u52D5\u30B9\u30CB\u30DA\u30C3\u30C8\u307E\u305F\u306F\n\u30B3\u30DE\u30F3\u30C9\u304C\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\n\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u306F\u8D77\u52D5\u8A2D\u5B9A\u3092\u30C6\u30B9\u30C8\u3059\u308B\u306E\u306B\u6709\u52B9\u3067\u3059\u3002jshell\u30C4\u30FC\u30EB\u306E\u4ECA\u5F8C\u306E\u5B9F\u884C\u306E\u305F\u3081\u306B\n\u305D\u308C\u3089\u3092\u4FDD\u6301\u3059\u308B\u306B\u306F\u3001\u6B21\u306E\u30B3\u30DE\u30F3\u30C9\u3092\u4F7F\u7528\u3057\u307E\u3059:\n\t/set start -retain\n\n-retain\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u8A2D\u5B9A\u306Fjshell\u30C4\u30FC\u30EB\u306E\u3053\u306E\u5B9F\u884C\u3068\u5C06\u6765\u306E\n\u5B9F\u884C\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n\n<file>\u307E\u305F\u306F\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u306A\u3044\u5F62\u5F0F\u306F\u3001\u8D77\u52D5\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n\u6CE8\u610F: \u8D77\u52D5\u304C\u6700\u5F8C\u306B\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u3053\u308C\u306F\u30D5\u30A1\u30A4\u30EB\u306E\u5185\u5BB9\u306E\u5F8C\u306B\n'set start'\u30B3\u30DE\u30F3\u30C9\u304C\u7D9A\u304F\u5F62\u5F0F\u3067\u8868\u793A\u3055\u308C\u307E\u3059\u3002
 
-startup.feedback = /set mode verbose -command    \n\n/set prompt verbose '\\njshell> '   '   ...> '    \n\n/set format verbose pre '|  '    \n/set format verbose post '%n'    \n/set format verbose errorpre '|  '    \n/set format verbose errorpost '%n'    \n\n/set format verbose errorline '{post}{pre}    {err}'    \n\n/set format verbose action '\u4F5C\u6210\u6E08' added-primary    \n/set format verbose action '\u5909\u66F4\u6E08' modified-primary    \n/set format verbose action '\u7F6E\u63DB\u6E08' replaced-primary    \n/set format verbose action '\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u6E08' overwrote-primary    \n/set format verbose action '\u524A\u9664\u6E08' dropped-primary    \n/set format verbose action '  \u66F4\u65B0\u4F5C\u6210\u6E08' added-update    \n/set format verbose action '  \u66F4\u65B0\u5909\u66F4\u6E08' modified-update    \n/set format verbose action '  \u66F4\u65B0\u7F6E\u63DB\u6E08' replaced-update    \n/set format verbose action '  \u66F4\u65B0\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u6E08' overwrote-update    \n/set format verbose action '  \u66F4\u65B0\u524A\u9664\u6E08' dropped-update    \n\n/set format verbose until '\u3001\u305F\u3060\u3057\u3001\u6B21\u307E\u3067\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u5316\u3067\u304D\u306A\u3044\u304B\u3001\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093:'   defined-class-primary    \n/set format verbose until '\u3001\u305F\u3060\u3057\u3001\u6B21\u307E\u3067\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093:'                      defined-interface-primary    \n/set format verbose until '\u3001\u305F\u3060\u3057\u3001\u6B21\u307E\u3067\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093:'                                  defined-enum,annotation-primary    \n/set format verbose until '\u3001\u305F\u3060\u3057\u3001\u6B21\u307E\u3067\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093:'                               defined-method-primary    \n/set format verbose until '\u3001\u305F\u3060\u3057\u3001\u6B21\u307E\u3067\u53C2\u7167\u3067\u304D\u307E\u305B\u3093:'                            notdefined-primary    \n/set format verbose until ' \u6B21\u307E\u3067\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u5316\u3067\u304D\u306A\u3044\u304B\u3001\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093:'          defined-class-update    \n/set format verbose until ' \u6B21\u307E\u3067\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093:'                              defined-interface-update    \n/set format verbose until ' \u6B21\u307E\u3067\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093:'                                      defined-method-update    \n/set format verbose until ' \u6B21\u307E\u3067\u53C2\u7167\u3067\u304D\u307E\u305B\u3093:'                                   notdefined-update    \n\n/set format verbose unrerr '{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u307E\u3057\u305F'                                           unresolved1-error0    \n/set format verbose unrerr '{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u307E\u3057\u305F'                                          unresolved2-error0    \n/set format verbose unrerr ' \u3053\u306E\u30A8\u30E9\u30FC\u306F\u4FEE\u6B63\u3055\u308C\u307E\u3057\u305F: {errors}'                                 unresolved0-error1    \n/set format verbose unrerr '{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u306E\u30A8\u30E9\u30FC\u306F\u4FEE\u6B63\u3055\u308C\u307E\u3057\u305F: {errors}'     unresolved1-error1    \n/set format verbose unrerr '{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u306E\u30A8\u30E9\u30FC\u306F\u4FEE\u6B63\u3055\u308C\u307E\u3057\u305F: {errors}'    unresolved2-error1    \n/set format verbose unrerr ' \u3053\u308C\u3089\u306E\u30A8\u30E9\u30FC\u306F\u4FEE\u6B63\u3055\u308C\u307E\u3057\u305F: {errors}'                              unresolved0-error2    \n/set format verbose unrerr \
-'{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u308C\u3089\u306E\u30A8\u30E9\u30FC\u306F\u4FEE\u6B63\u3055\u308C\u307E\u3057\u305F: {errors}'  unresolved1-error2    \n/set format verbose unrerr '{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u308C\u3089\u306E\u30A8\u30E9\u30FC\u306F\u4FEE\u6B63\u3055\u308C\u307E\u3057\u305F: {errors}' unresolved2-error2    \n\n/set format verbose resolve '{until}{unrerr}'                                                   added,modified,replaced,used    \n\n/set format verbose typeKind '\u30AF\u30E9\u30B9'                  class    \n/set format verbose typeKind '\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9'              interface    \n/set format verbose typeKind '\u5217\u6319\u578B'                   enum    \n/set format verbose typeKind '\u6CE8\u91C8\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9'   annotation    \n\n/set format verbose result '{name} ==> {value}{post}'                                        added,modified,replaced-ok-primary    \n\n/set format verbose display '{result}{pre}\u30B9\u30AF\u30E9\u30C3\u30C1\u5909\u6570{name}\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F : {type}{post}'    expression-added,modified,replaced-primary    \n/set format verbose display '{result}{pre}{name}\u306E\u5024 : {type}{post}'                    varvalue-primary    \n/set format verbose display '{result}{pre}{name}\u306B\u5272\u308A\u5F53\u3066\u3089\u308C\u307E\u3057\u305F : {type}{post}'                 assignment-primary    \n/set format verbose display '{result}{pre}{action} \u5909\u6570 {name} : {type}{resolve}{post}'  varinit,vardecl    \n/set format verbose display '{pre}{action} \u5909\u6570 {name}{resolve}{post}'                   vardecl,varinit-notdefined    \n/set format verbose display '{pre}{action} \u5909\u6570 {name}{post}'                            dropped-vardecl,varinit,expression    \n/set format verbose display '{pre}{action} \u5909\u6570 {name}\u3001null\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F{post}'             replaced-vardecl,varinit-ok-update    \n\n/set format verbose display '{pre}{action} {typeKind} {name}{resolve}{post}'                 class,interface,enum,annotation    \n/set format verbose display '{pre}{action} \u30E1\u30BD\u30C3\u30C9 {name}({type})\u3092\u547C\u3073\u51FA\u305D\u3046\u3068\u3057\u307E\u3057\u305F{resolve}{post}'             method    \n\n/set format verbose display '{pre}{typeKind} {name}\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F{resolve}{post}'         used-class,interface,enum,annotation    \n/set format verbose display '{pre}\u30E1\u30BD\u30C3\u30C9{name}({type})\u3092\u547C\u3073\u51FA\u305D\u3046\u3068\u3057\u307E\u3057\u305F{resolve}{post}'    used-method    \n\n/set truncation verbose 80\n/set truncation verbose 1000                                                                  varvalue,expression\n\n/set mode normal -command verbose    \n/set format normal display ''                                                               added,modified,replaced,overwrote,dropped-update    \n/set format normal display '{pre}{action} \u5909\u6570 {name}\u3001null\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F{post}' replaced-vardecl,varinit-ok-update    \n/set format normal display '{result}'                                                       added,modified,replaced-expression,varvalue,assignment,varinit,vardecl-ok-primary    \n/set mode concise -quiet normal    \n\n/set prompt concise 'jshell> '   '   ...> '    \n\n/set format concise display ''                                                              class,interface,enum,annotation,method,assignment,varinit,vardecl-ok    \n\n/set feedback normal    \n\n/set mode silent -quiet    \n/set prompt silent '-> ' '>> '    \n/set format silent pre '|  '    \n/set format silent post '%n'    \n/set format silent errorpre '|  '    \n/set format silent errorpost '%n'    \n/set format silent display ''    \n
+startup.feedback = /set mode verbose -command    \n\n/set prompt verbose '\\njshell> '   '   ...> '    \n\n/set format verbose pre '|  '    \n/set format verbose post '%n'    \n/set format verbose errorpre '|  '    \n/set format verbose errorpost '%n'    \n\n/set format verbose errorline '{post}{pre}    {err}'    \n\n/set format verbose action '\u6B21\u3092\u4F5C\u6210\u3057\u307E\u3057\u305F:' added-primary    \n/set format verbose action '\u6B21\u3092\u5909\u66F4\u3057\u307E\u3057\u305F:' modified-primary    \n/set format verbose action '\u6B21\u3092\u7F6E\u63DB\u3057\u307E\u3057\u305F:' replaced-primary    \n/set format verbose action '\u6B21\u3092\u4E0A\u66F8\u304D\u3057\u307E\u3057\u305F:' overwrote-primary    \n/set format verbose action '\u6B21\u3092\u524A\u9664\u3057\u307E\u3057\u305F:' dropped-primary    \n/set format verbose action '  \u6B21\u3092\u66F4\u65B0/\u4F5C\u6210\u3057\u307E\u3057\u305F:' added-update    \n/set format verbose action '  \u6B21\u3092\u66F4\u65B0/\u5909\u66F4\u3057\u307E\u3057\u305F:' modified-update    \n/set format verbose action '  \u6B21\u3092\u66F4\u65B0/\u7F6E\u63DB\u3057\u307E\u3057\u305F:' replaced-update    \n/set format verbose action '  \u6B21\u3092\u66F4\u65B0/\u4E0A\u66F8\u304D\u3057\u307E\u3057\u305F:' overwrote-update    \n/set format verbose action '  \u6B21\u3092\u66F4\u65B0/\u524A\u9664\u3057\u307E\u3057\u305F:' dropped-update    \n\n/set format verbose until '\u307E\u3067\u3001\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u5316\u3067\u304D\u306A\u3044\u304B\u3001\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093'   defined-class-primary    \n/set format verbose until '\u307E\u3067\u3001\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093'                      defined-interface-primary    \n/set format verbose until '\u307E\u3067\u3001\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093'                                  defined-enum,annotation-primary    \n/set format verbose until '\u307E\u3067\u3001\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093'                               defined-method-primary    \n/set format verbose until '\u307E\u3067\u3001\u53C2\u7167\u3067\u304D\u307E\u305B\u3093'                            notdefined-primary    \n/set format verbose until '\u307E\u3067\u3001\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u5316\u3067\u304D\u306A\u3044\u304B\u3001\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093'          defined-class-update    \n/set format verbose until '\u307E\u3067\u3001\u305D\u306E\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093'                              defined-interface-update    \n/set format verbose until '\u307E\u3067\u3001\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093'                                      defined-method-update    \n/set format verbose until '\u307E\u3067\u3001\u53C2\u7167\u3067\u304D\u307E\u305B\u3093'                                   notdefined-update    \n\n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u308B'                                           unresolved1-error0    \n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u308B'                                          unresolved2-error0    \n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001\u3053\u306E\u30A8\u30E9\u30FC({errors})\u304C\u4FEE\u6B63\u3055\u308C\u308B'                                 unresolved0-error1    \n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u306E\u30A8\u30E9\u30FC({errors})\u304C\u4FEE\u6B63\u3055\u308C\u308B'     unresolved1-error1    \n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u306E\u30A8\u30E9\u30FC({errors})\u304C\u4FEE\u6B63\u3055\u308C\u308B'    unresolved2-error1    \n/set format verbose unrerr \
+'\u3002\u3057\u304B\u3057\u3001\u3053\u308C\u3089\u306E\u30A8\u30E9\u30FC({errors})\u304C\u4FEE\u6B63\u3055\u308C\u308B'                              unresolved0-error2    \n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u308C\u3089\u306E\u30A8\u30E9\u30FC({errors})\u304C\u4FEE\u6B63\u3055\u308C\u308B'  unresolved1-error2    \n/set format verbose unrerr '\u3002\u3057\u304B\u3057\u3001{unresolved}\u304C\u5BA3\u8A00\u3055\u308C\u3001\u3053\u308C\u3089\u306E\u30A8\u30E9\u30FC({errors})\u304C\u4FEE\u6B63\u3055\u308C\u308B' unresolved2-error2    \n\n/set format verbose resolve '{unrerr}{until}'                                                   defined,notdefined-added,modified,replaced,used    \n\n/set format verbose typeKind '\u30AF\u30E9\u30B9'                  class    \n/set format verbose typeKind '\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9'              interface    \n/set format verbose typeKind '\u5217\u6319\u578B'                   enum    \n/set format verbose typeKind '\u6CE8\u91C8\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9'   annotation    \n\n/set format verbose result '{name} ==> {value}{post}'                                        added,modified,replaced-ok-primary    \n\n/set format verbose display '{result}{pre}\u30B9\u30AF\u30E9\u30C3\u30C1\u5909\u6570{name} : {type}\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F{post}'    expression-added,modified,replaced-primary    \n/set format verbose display '{result}{pre}{name} : {type}\u306E\u5024{post}'                    varvalue-added,modified,replaced-primary    \n/set format verbose display '{result}{pre}{name} : {type}\u306B\u5272\u308A\u5F53\u3066\u3089\u308C\u307E\u3057\u305F{post}'                 assignment-primary    \n/set format verbose display '{result}{pre}{action} \u5909\u6570 {name} : {type}{resolve}{post}'  varinit,vardecl    \n/set format verbose display '{pre}{action} \u5909\u6570 {name}{resolve}{post}'                   vardecl,varinit-notdefined    \n/set format verbose display '{pre}{action} \u5909\u6570 {name}{post}'                            dropped-vardecl,varinit,expression    \n/set format verbose display '{pre}{action} \u5909\u6570 {name}\u3002null\u306B\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F{post}'             replaced-vardecl,varinit-ok-update    \n\n/set format verbose display '{pre}{action} {typeKind} {name}{resolve}{post}'                 class,interface,enum,annotation    \n/set format verbose display '{pre}{action} \u30E1\u30BD\u30C3\u30C9 {name}({type}){resolve}{post}' method    \n\n/set format verbose display '{pre}{typeKind} {name}\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F{resolve}{post}'         used-class,interface,enum,annotation    \n/set format verbose display '{pre}\u30E1\u30BD\u30C3\u30C9{name}({type})\u3092\u547C\u3073\u51FA\u305D\u3046\u3068\u3057\u307E\u3057\u305F{resolve}{post}'    used-method    \n\n/set truncation verbose 80\n/set truncation verbose 1000                                                                  varvalue,expression\n\n/set mode normal -command verbose    \n/set format normal display ''                                                               added,modified,replaced,overwrote,dropped-update    \n/set format normal display '{pre}{action} \u5909\u6570 {name}\u3001null\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F{post}' replaced-vardecl,varinit-ok-update    \n/set format normal display '{result}'                                                       added,modified,replaced-expression,varvalue,assignment,varinit,vardecl-ok-primary    \n/set mode concise -quiet normal    \n\n/set prompt concise 'jshell> '   '   ...> '    \n\n/set format concise display ''                                                              class,interface,enum,annotation,method,assignment,varinit,vardecl-ok    \n\n/set feedback normal    \n\n/set mode silent -quiet    \n/set prompt silent '-> ' '>> '    \
+\n/set truncation silent 80\n/set truncation silent 1000                                                                  varvalue,expression\n/set format silent pre '|  '    \n/set format silent post '%n'    \n/set format silent errorpre '|  '    \n/set format silent errorpost '%n'    \n/set format silent display ''    \n
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n_zh_CN.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n_zh_CN.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -24,10 +24,11 @@
 #
 
 jshell.msg.welcome =\u6B22\u8FCE\u4F7F\u7528 JShell -- \u7248\u672C {0}\n\u8981\u5927\u81F4\u4E86\u89E3\u8BE5\u7248\u672C, \u8BF7\u952E\u5165: /help intro\n
-jshell.err.opt.classpath.conflict = \u51B2\u7A81\u7684 -classpath \u9009\u9879\u3002
-jshell.err.opt.classpath.arg = \u7F3A\u5C11 -classpath \u7684\u53C2\u6570\u3002
-jshell.err.opt.feedback.arg = -feedback \u7F3A\u5C11\u53C2\u6570\u3002\u9700\u8981\u6A21\u5F0F\u3002
-jshell.err.opt.startup.one = \u53EA\u80FD\u4F7F\u7528\u4E00\u4E2A -startup \u6216 -nostartup \u9009\u9879\u3002
+jshell.err.opt.arg = \u7F3A\u5C11 {0} \u7684\u53C2\u6570\u3002
+jshell.err.opt.invalid = \u65E0\u6548\u7684\u9009\u9879: {0}\u3002
+jshell.err.opt.one = \u53EA\u80FD\u4F7F\u7528\u4E00\u4E2A {0} \u9009\u9879\u3002
+jshell.err.opt.startup.one = \u53EA\u80FD\u4F7F\u7528\u4E00\u4E2A --startup \u6216 --no-startup \u9009\u9879\u3002
+jshell.err.opt.feedback.one = \u53EA\u80FD\u4F7F\u7528\u4E00\u4E2A\u53CD\u9988\u9009\u9879 (--feedback, -q, -s \u6216 -v)\u3002
 jshell.err.opt.unknown = \u672A\u77E5\u9009\u9879: {0}
 
 jshell.msg.terminated =\u72B6\u6001\u5F15\u64CE\u5DF2\u7EC8\u6B62\u3002\n\u4F7F\u7528 /reload -restore \u53EF\u8FD8\u539F\u5B9A\u4E49
@@ -47,10 +48,16 @@
 
 jshell.err.no.such.command.or.snippet.id = \u6CA1\u6709\u8FD9\u6837\u7684\u547D\u4EE4\u6216\u7247\u6BB5 id: {0}
 jshell.err.command.ambiguous = \u547D\u4EE4 ''{0}'' \u4E0D\u660E\u786E: {1}
-jshell.err.set.editor.arg = ''/set editor'' \u547D\u4EE4\u8981\u6C42\u8DEF\u5F84\u53C2\u6570
 jshell.msg.set.editor.set = \u7F16\u8F91\u5668\u8BBE\u7F6E\u4E3A: {0}
+jshell.msg.set.editor.retain = \u4FDD\u7559\u7684\u7F16\u8F91\u5668\u8BBE\u7F6E: {0}
 jshell.err.cant.launch.editor = \u65E0\u6CD5\u542F\u52A8\u7F16\u8F91\u5668 -- \u610F\u5916\u7684\u5F02\u5E38\u9519\u8BEF: {0}
 jshell.msg.try.set.editor = \u8BF7\u5C1D\u8BD5\u901A\u8FC7 /set editor \u6765\u4F7F\u7528\u5916\u90E8\u7F16\u8F91\u5668\u3002
+jshell.msg.press.return.to.leave.edit.mode = \u6309\u201C\u8FD4\u56DE\u201D\u9000\u51FA\u7F16\u8F91\u6A21\u5F0F\u3002
+jshell.err.wait.applies.to.external.editor = -wait \u9002\u7528\u4E8E\u5916\u90E8\u7F16\u8F91\u5668
+
+jshell.err.setting.to.retain.must.be.specified = \u5FC5\u987B\u6307\u5B9A\u8981\u4FDD\u7559\u7684\u8BBE\u7F6E -- {0}
+jshell.msg.set.show.mode.settings = \n\u8981\u663E\u793A\u6A21\u5F0F\u8BBE\u7F6E, \u8BF7\u4F7F\u7528 ''/set prompt'', ''/set truncation'', ...\n\u6216\u8005\u4F7F\u7528 ''/set mode'' \u540E\u8DDF\u53CD\u9988\u6A21\u5F0F\u540D\u79F0\u3002
+jshell.err.continuation.prompt.required = \u66F4\u591A\u63D0\u793A\u662F\u5FC5\u586B\u7684 -- {0}
 
 jshell.msg.try.command.without.args = \u5C1D\u8BD5\u4F7F\u7528\u4E0D\u5E26\u53C2\u6570\u7684 ''{0}''\u3002
 jshell.msg.no.active = \u6CA1\u6709\u6D3B\u52A8\u5B9A\u4E49\u3002
@@ -91,12 +98,10 @@
 jshell.err.mode.name = \u9884\u671F\u53CD\u9988\u6A21\u5F0F\u540D\u79F0: {0}
 jshell.err.missing.mode = \u7F3A\u5C11\u53CD\u9988\u6A21\u5F0F -- {0}
 jshell.err.field.name = \u9884\u671F\u5B57\u6BB5\u540D: {0} -- {1}
-jshell.err.missing.field = \u7F3A\u5C11\u5B57\u6BB5\u540D -- {0}
 jshell.err.mode.unknown = \u672A\u6307\u5B9A\u53CD\u9988\u6A21\u5F0F: {0} -- {1}
 
 jshell.err.feedback.does.not.match.mode = \u4E0D\u5339\u914D\u4EFB\u4F55\u5F53\u524D\u53CD\u9988\u6A21\u5F0F: {0} -- {1}
 jshell.err.feedback.ambiguous.mode = \u5339\u914D\u4E86\u591A\u4E2A\u5F53\u524D\u53CD\u9988\u6A21\u5F0F: {0} -- {1}
-jshell.err.feedback.expected.format = \u7F3A\u5C11\u9884\u671F\u683C\u5F0F -- {0}
 jshell.err.feedback.must.be.quoted = \u683C\u5F0F ''{0}'' \u5FC5\u987B\u4F7F\u7528\u5F15\u53F7\u62EC\u8D77\u6765 -- {1}
 jshell.err.feedback.not.a.valid.selector = \u4E0D\u662F ''{1}'' \u4E2D\u6709\u6548\u7684\u9009\u62E9\u5668 ''{0}'' -- {2}
 jshell.err.feedback.multiple.sections = \u9009\u62E9\u5668\u7C7B\u578B\u5728 ''{1}'' \u4E2D\u9009\u62E9\u5668\u5217\u8868 ''{0}'' \u7684\u591A\u4E2A\u90E8\u5206\u4E2D -- {2}
@@ -104,21 +109,24 @@
 
 jshell.msg.feedback.new.mode = \u5DF2\u521B\u5EFA\u65B0\u7684\u53CD\u9988\u6A21\u5F0F: {0}
 jshell.msg.feedback.mode = \u53CD\u9988\u6A21\u5F0F: {0}
-jshell.msg.feedback.mode.following = \u53CD\u9988\u6A21\u5F0F\u5E94\u8BE5\u4E3A\u4EE5\u4E0B\u4E4B\u4E00:
+jshell.msg.feedback.mode.following = \u53EF\u7528\u7684\u53CD\u9988\u6A21\u5F0F:
+jshell.msg.feedback.retained.mode.following = \u4FDD\u7559\u7684\u53CD\u9988\u6A21\u5F0F:
+jshell.err.mode.creation = \u8981\u521B\u5EFA\u65B0\u6A21\u5F0F, \u5FC5\u987B\u4F7F\u7528 -command \u6216 -quiet \u9009\u9879 -- {0}
+jshell.err.mode.exists = \u8981\u521B\u5EFA\u7684\u6A21\u5F0F\u5DF2\u5B58\u5728: {0} -- {1}
 
 jshell.err.truncation.expected.length = \u9884\u671F\u622A\u65AD\u957F\u5EA6 -- {0}
 jshell.err.truncation.length.not.integer = \u622A\u65AD\u957F\u5EA6\u5FC5\u987B\u4E3A\u6574\u6570: {0} -- {1}
 
 jshell.err.not.valid.with.predefined.mode = \u5BF9\u4E8E\u9884\u5B9A\u4E49\u7684\u6A21\u5F0F\u65E0\u6548: {0} -- {1}
-jshell.err.retained.feedback.mode.must.be.retained.or.predefined = ''/retain feedback <\u6A21\u5F0F>'' \u8981\u6C42 <\u6A21\u5F0F> \u4E3A\u9884\u5B9A\u4E49\u6216\u8005\u5DF2\u7ECF\u4F7F\u7528 ''/retain mode'' \u4FDD\u7559 -- {0}
+jshell.err.retained.feedback.mode.must.be.retained.or.predefined = ''/set feedback -retain <\u6A21\u5F0F>'' \u8981\u6C42 <\u6A21\u5F0F> \u4E3A\u9884\u5B9A\u4E49\u6A21\u5F0F\u6216\u8005\u5DF2\u7ECF\u4F7F\u7528 ''/set mode -retain'' \u4FDD\u7559 -- {0}
 
 jshell.err.unknown.option = \u672A\u77E5\u9009\u9879: {0} -- {1}
-jshell.err.default.option.or.program = \u6307\u5B9A -default \u9009\u9879\u6216\u7A0B\u5E8F, \u4F46\u4E0D\u80FD\u540C\u65F6\u6307\u5B9A -- {0}
-jshell.err.option.or.filename = \u6307\u5B9A\u4E00\u4E2A\u9009\u9879\u6216\u8005\u4E00\u4E2A\u542F\u52A8\u6587\u4EF6\u540D -- {0}
+jshell.err.default.option.or.program = \u6307\u5B9A -default \u9009\u9879, -delete \u9009\u9879\u6216\u7A0B\u5E8F -- {0}
+jshell.err.option.or.filename = \u6700\u591A\u6307\u5B9A -default, -none \u6216\u542F\u52A8\u6587\u4EF6\u540D\u4E2D\u7684\u4E00\u9879 -- {0}
 jshell.err.unexpected.at.end = \u547D\u4EE4\u7ED3\u5C3E\u5904\u9047\u5230\u610F\u5916\u7684\u53C2\u6570: {0} -- {1}
 jshell.err.conflicting.options = \u51B2\u7A81\u7684\u9009\u9879 -- {0}
 jshell.err.cannot.delete.current.mode = \u65E0\u6CD5\u5220\u9664\u5F53\u524D\u53CD\u9988\u6A21\u5F0F ''{0}'', \u8BF7\u5148\u4F7F\u7528 ''/set feedback'' -- {1}
-jshell.err.cannot.delete.retained.mode = \u65E0\u6CD5\u5220\u9664\u4FDD\u7559\u7684\u53CD\u9988\u6A21\u5F0F ''{0}'', \u8BF7\u5148\u4F7F\u7528 ''/retain feedback'' -- {1}
+jshell.err.cannot.delete.retained.mode = \u65E0\u6CD5\u5220\u9664\u4FDD\u7559\u7684\u53CD\u9988\u6A21\u5F0F ''{0}'', \u8BF7\u5148\u4F7F\u7528 ''/set feedback -retain'' -- {1}
 jshell.err.may.not.specify.options.and.snippets = \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u9009\u9879\u548C\u7247\u6BB5: {0}
 jshell.err.no.such.snippets = \u6CA1\u6709\u6B64\u7C7B\u7247\u6BB5: {0}
 jshell.err.the.snippet.cannot.be.used.with.this.command = \u6B64\u547D\u4EE4\u4E0D\u63A5\u53D7\u7247\u6BB5 ''{0}'' : {1}
@@ -133,7 +141,8 @@
 jshell.console.incomplete = \n\u7ED3\u679C\u53EF\u80FD\u4E0D\u5B8C\u6574; \u8BF7\u7A0D\u5019\u91CD\u8BD5\u4EE5\u83B7\u53D6\u5B8C\u6574\u7ED3\u679C\u3002
 
 
-help.usage = \u7528\u6CD5:   jshell <\u9009\u9879> <\u52A0\u8F7D\u6587\u4EF6>\n\u5176\u4E2D, \u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:\n    -classpath <\u8DEF\u5F84>    \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n    -cp <\u8DEF\u5F84>           \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n    -startup <\u6587\u4EF6>      \u5BF9\u542F\u52A8\u5B9A\u4E49\u6267\u884C\u5355\u6B21\u66FF\u6362\n    -nostartup           \u4E0D\u8FD0\u884C\u542F\u52A8\u5B9A\u4E49\n    -feedback <\u6A21\u5F0F>     \u6307\u5B9A\u521D\u59CB\u53CD\u9988\u6A21\u5F0F\u3002\u8BE5\u6A21\u5F0F\u53EF\u4EE5\u662F\n                         \u9884\u5B9A\u4E49\u7684 (silent, concise, normal \u6216 verbose), \n                         \u4E5F\u53EF\u662F\u4EE5\u524D\u7528\u6237\u5B9A\u4E49\u7684\n    -q                   \u65E0\u63D0\u793A\u53CD\u9988\u3002\u7B49\u540C\u4E8E: -feedback concise\n    -qq                  \u771F\u6B63\u65E0\u63D0\u793A\u53CD\u9988\u3002\u7B49\u540C\u4E8E: -feedback silent\n    -v                   \u8BE6\u7EC6\u53CD\u9988\u3002\u7B49\u540C\u4E8E: -feedback verbose\n    -J<\u6807\u8BB0>             \u76F4\u63A5\u5C06 <\u6807\u8BB0> \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\u3002\n                         \u4E3A\u6BCF\u4E2A\u8FD0\u884C\u65F6\u6807\u8BB0\u6216\u6807\u8BB0\u53C2\u6570\u4F7F\u7528\u4E00\u4E2A -J\n    -R<\u6807\u8BB0>             \u5C06 <\u6807\u8BB0> \u4F20\u9012\u5230\u8FDC\u7A0B\u8FD0\u884C\u65F6\u7CFB\u7EDF\u3002\n                         \u4E3A\u6BCF\u4E2A\u8FDC\u7A0B\u6807\u8BB0\u6216\u6807\u8BB0\u53C2\u6570\u4F7F\u7528\u4E00\u4E2A -R\n    -help                \u8F93\u51FA\u6B64\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\n    -version             \u7248\u672C\u4FE1\u606F\n
+help.usage = \u7528\u6CD5:   jshell <\u9009\u9879> <\u52A0\u8F7D\u6587\u4EF6>\n\u5176\u4E2D, \u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:\n    --class-path <\u8DEF\u5F84>   \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n    --module-path <\u8DEF\u5F84>  \u6307\u5B9A\u67E5\u627E\u5E94\u7528\u7A0B\u5E8F\u6A21\u5757\u7684\u4F4D\u7F6E\n    --add-modules <\u6A21\u5757>(,<\u6A21\u5757>)*\n                          \u6307\u5B9A\u8981\u89E3\u6790\u7684\u6A21\u5757; \u5982\u679C <\u6A21\u5757> \n                          \u4E3A ALL-MODULE-PATH, \u5219\u4E3A\u6A21\u5757\u8DEF\u5F84\u4E2D\u7684\u6240\u6709\u6A21\u5757\n    --startup <\u6587\u4EF6>      \u5BF9\u542F\u52A8\u5B9A\u4E49\u6267\u884C\u5355\u6B21\u66FF\u6362\n    --no-startup          \u4E0D\u8FD0\u884C\u542F\u52A8\u5B9A\u4E49\n    --feedback <\u6A21\u5F0F>     \u6307\u5B9A\u521D\u59CB\u53CD\u9988\u6A21\u5F0F\u3002\u8BE5\u6A21\u5F0F\u53EF\u4EE5\u662F\n                           \u9884\u5B9A\u4E49\u7684 (silent, concise, normal \u6216 verbose), \n                           \u4E5F\u53EF\u662F\u4EE5\u524D\u7528\u6237\u5B9A\u4E49\u7684\n    -q                    \u65E0\u63D0\u793A\u53CD\u9988\u3002\u7B49\u540C\u4E8E: --feedback concise\n    -s                    \u771F\u6B63\u65E0\u63D0\u793A\u53CD\u9988\u3002\u7B49\u540C\u4E8E: --feedback silent\n    -v                    \u8BE6\u7EC6\u53CD\u9988\u3002\u7B49\u540C\u4E8E: --feedback verbose\n    -J<\u6807\u8BB0>              \u76F4\u63A5\u5C06 <\u6807\u8BB0> \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\u3002\n                           \u4E3A\u6BCF\u4E2A\u8FD0\u884C\u65F6\u6807\u8BB0\u6216\u6807\u8BB0\u53C2\u6570\u4F7F\u7528\u4E00\u4E2A -J\n    -R<\u6807\u8BB0>              \u5C06 <\u6807\u8BB0> \u4F20\u9012\u5230\u8FDC\u7A0B\u8FD0\u884C\u65F6\u7CFB\u7EDF\u3002\n                           \u4E3A\u6BCF\u4E2A\u8FDC\u7A0B\u6807\u8BB0\u6216\u6807\u8BB0\u53C2\u6570\u4F7F\u7528\u4E00\u4E2A -R\n    -C<\u6807\u8BB0>              \u5C06 <\u6807\u8BB0> \u4F20\u9012\u5230\u7F16\u8BD1\u5668\u3002\n                           \u4E3A\u6BCF\u4E2A\u7F16\u8BD1\u5668\u6807\u8BB0\u6216\u6807\u8BB0\u53C2\u6570\u4F7F\u7528\u4E00\u4E2A -C\n    --help                \u8F93\u51FA\u6807\u51C6\u9009\u9879\u7684\u6B64\u63D0\u8981\n    --version             \u7248\u672C\u4FE1\u606F\n    -X                    \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u5E2E\u52A9\n
+help.usage.x = \    --add-exports <\u6A21\u5757>/<\u7A0B\u5E8F\u5305>   \u5C06\u6307\u5B9A\u7684\u6A21\u5757\u4E13\u7528\u7A0B\u5E8F\u5305\u5BFC\u51FA\u5230\u7247\u6BB5\n    \n\u8FD9\u4E9B\u9009\u9879\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002\n
 
 help.list.summary = \u5217\u51FA\u60A8\u952E\u5165\u7684\u6E90
 help.list.args = [<\u540D\u79F0\u6216 id>|-all|-start]
@@ -181,7 +190,7 @@
 
 help.reload.summary = \u91CD\u542F\u548C\u91CD\u653E\u76F8\u5173\u5386\u53F2\u8BB0\u5F55 -- \u5F53\u524D\u5386\u53F2\u8BB0\u5F55\u6216\u4E0A\u4E00\u4E2A\u5386\u53F2\u8BB0\u5F55 (-restore)
 help.reload.args = [-restore] [-quiet]
-help.reload =\u91CD\u542F jshell \u5DE5\u5177\u4EE3\u7801\u548C\u6267\u884C\u72B6\u6001, \u7136\u540E\u6309\u7167 jshell \u6709\u6548\n\u547D\u4EE4\u548C\u6709\u6548\u7247\u6BB5\u7684\u8F93\u5165\u987A\u5E8F\u91CD\u653E\u6BCF\u4E2A\u547D\u4EE4\u548C\u6BCF\u4E2A\u7247\u6BB5\u3002\n\n/reload\n\t\u91CD\u542F\u548C\u91CD\u653E\u81EA\u8FDB\u5165 jshell \u4EE5\u6765\u7684\u6709\u6548\u5386\u53F2\u8BB0\u5F55,\n\t\u6216\u8005\u6267\u884C /reset \u6216 /reload \u547D\u4EE4\u4E2D\u6700\u8FD1\u7684\u90A3\u4E2A\n\t\u547D\u4EE4\u3002\n\n/reload -restore\n\t\u91CD\u542F\u5E76\u91CD\u653E\u4E0A\u4E00\u6B21\u8FDB\u5165 jshell \u4EE5\u53CA\u6700\u8FD1\u8FDB\u5165 jshell\n\t\u4E4B\u95F4\u7684\u6709\u6548\u5386\u53F2\u8BB0\u5F55, \u6216\u8005\u6267\u884C /reset \u6216 /reload\n\t\u547D\u4EE4\u3002\u8FD9\u8FDB\u800C\u53EF\u7528\u4E8E\u8FD8\u539F\u4E0A\u4E00\u4E2A\n\tjshell \u5DE5\u5177\u4F1A\u8BDD\u3002\n\n/reload [-restore] -quiet\n\t\u4F7F\u7528 '-quiet' \u53C2\u6570\u65F6, \u4E0D\u663E\u793A\u91CD\u653E\u3002\u5C06\u663E\u793A\u9519\u8BEF\u3002
+help.reload =\u91CD\u7F6E jshell \u5DE5\u5177\u4EE3\u7801\u548C\u6267\u884C\u72B6\u6001, \u7136\u540E\u6309\u7167\u5404\u6709\u6548\u7247\u6BB5\u548C\n\u4EFB\u4F55 /drop \u6216 /classpath \u547D\u4EE4\u7684\u8F93\u5165\u987A\u5E8F\u91CD\u653E\u5B83\u4EEC\u3002\n\n/reload\n\t\u91CD\u7F6E\u548C\u91CD\u653E\u81EA\u8FDB\u5165 jshell \u4EE5\u6765\u7684\u6709\u6548\u5386\u53F2\u8BB0\u5F55, \n\t\u6216\u8005\u6267\u884C /reset \u6216 /reload \u547D\u4EE4\u4E2D\u6700\u65B0\u7684\u90A3\u4E2A\n\t\u547D\u4EE4\u3002\n\n/reload -restore\n\t\u91CD\u7F6E\u5E76\u91CD\u653E\u4E0A\u4E00\u6B21\u8FDB\u5165 jshell \u4EE5\u53CA\u6700\u8FD1\u8FDB\u5165 jshell\n\t\u4E4B\u95F4\u7684\u6709\u6548\u5386\u53F2\u8BB0\u5F55, \u6216\u8005\u6267\u884C /reset \u6216 /reload\n\t\u547D\u4EE4\u3002\u8FD9\u8FDB\u800C\u53EF\u7528\u4E8E\u8FD8\u539F\u4E0A\u4E00\u4E2A\n\tjshell \u5DE5\u5177\u4F1A\u8BDD\u3002\n\n/reload [-restore] -quiet\n\t\u4F7F\u7528 '-quiet' \u53C2\u6570\u65F6, \u4E0D\u663E\u793A\u91CD\u653E\u3002\u5C06\u663E\u793A\u9519\u8BEF\u3002
 
 help.classpath.summary = \u5C06\u8DEF\u5F84\u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84
 help.classpath.args = <path>
@@ -201,11 +210,7 @@
 
 help.set.summary = \u8BBE\u7F6E jshell \u914D\u7F6E\u4FE1\u606F
 help.set.args = editor|start|feedback|mode|prompt|truncation|format ...
-help.set =\u8BBE\u7F6E jshell \u914D\u7F6E\u4FE1\u606F, \u5305\u62EC:\n\u8981\u4F7F\u7528\u7684\u5916\u90E8\u7F16\u8F91\u5668, \u8981\u4F7F\u7528\u7684\u542F\u52A8\u5B9A\u4E49, \u65B0\u7684\u53CD\u9988\u6A21\u5F0F,\n\u547D\u4EE4\u63D0\u793A\u7B26, \u8981\u4F7F\u7528\u7684\u53CD\u9988\u6A21\u5F0F\u6216\u8F93\u51FA\u7684\u683C\u5F0F\u3002\n\n/set editor <\u547D\u4EE4> <\u53EF\u9009\u53C2\u6570>...\n\t\u6307\u5B9A\u8981\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4\u3002\n\t<\u547D\u4EE4> \u662F\u4E0E\u64CD\u4F5C\u7CFB\u7EDF\u76F8\u5173\u7684\u5B57\u7B26\u4E32\u3002\n\n/set start <\u6587\u4EF6>\n\t\u6307\u5B9A <\u6587\u4EF6> \u7684\u5185\u5BB9\u5C06\u6210\u4E3A\u9ED8\u8BA4\u542F\u52A8\u7247\u6BB5\u548C\u547D\u4EE4\u3002\n\n/set feedback <\u6A21\u5F0F>\n\t\u8BBE\u7F6E\u7528\u4E8E\u63CF\u8FF0\u4E3A\u6240\u8F93\u5165\u7247\u6BB5\u548C\u547D\u4EE4\u663E\u793A\u7684\u53CD\u9988\u7684\u53CD\u9988\u6A21\u5F0F\u3002\n\n/set mode <\u6A21\u5F0F> [<\u65E7\u6A21\u5F0F>] [-command|-quiet|-delete]\n\t\u521B\u5EFA\u6216\u66F4\u65B0\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F, \u53EF\u4EE5\u9009\u62E9\u4ECE\u73B0\u6709\u6A21\u5F0F\u590D\u5236\u3002\n\n/set prompt <\u6A21\u5F0F> "<\u63D0\u793A>" "<\u66F4\u591A\u63D0\u793A>"\n\t\u8BBE\u7F6E\u4E3A\u7ED9\u5B9A\u53CD\u9988\u6A21\u5F0F\u663E\u793A\u7684\u63D0\u793A\u7B26\u3002\n\n/set truncation <\u6A21\u5F0F> <\u957F\u5EA6> <\u9009\u62E9\u5668>...\n\t\u8BBE\u7F6E\u663E\u793A\u503C\u7684\u6700\u5927\u957F\u5EA6\n/set format <\u6A21\u5F0F> <\u5B57\u6BB5> "<\u683C\u5F0F>" <\u9009\u62E9\u5668>...\n\t\u901A\u8FC7\u8BBE\u7F6E\u5F53\u9009\u62E9\u5668\u5339\u914D\u65F6\u5B57\u6BB5\u7684\u683C\u5F0F\u6765\u914D\u7F6E\u53CD\u9988\u6A21\u5F0F\u3002\n\n\u8981\u83B7\u53D6\u6709\u5173\u5176\u4E2D\u4E00\u4E2A\u683C\u5F0F\u7684\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u5BF9\u6307\u5B9A\u7684\u683C\u5F0F\u4F7F\u7528 /help\u3002\n\u4F8B\u5982:   /help /set format
-
-help.retain.summary = \u4E3A\u540E\u7EED\u4F1A\u8BDD\u4FDD\u7559 jshell \u914D\u7F6E\u4FE1\u606F
-help.retain.args = editor|start|feedback|mode
-help.retain =\u4FDD\u7559 jshell \u914D\u7F6E\u4FE1\u606F\u4EE5\u4F9B jshell \u5DE5\u5177\u5728\u4EE5\u540E\u8C03\u7528,\n\u8FD9\u4E9B\u4FE1\u606F\u5305\u62EC: \u8981\u4F7F\u7528\u7684\u5916\u90E8\u7F16\u8F91\u5668, \u8981\u4F7F\u7528\u7684\u542F\u52A8\u5B9A\u4E49, \n\u53CD\u9988\u6A21\u5F0F\u7684\u914D\u7F6E, \u6216\u8005\u8981\u4F7F\u7528\u7684\u53CD\u9988\u6A21\u5F0F\u3002\n\n/retain editor [<\u547D\u4EE4> <\u53EF\u9009\u53C2\u6570>...]\n\t\u6307\u5B9A\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4\u3002\n\t<\u547D\u4EE4> \u662F\u4E0E\u64CD\u4F5C\u7CFB\u7EDF\u76F8\u5173\u7684\u5B57\u7B26\u4E32\u3002\n\n/retain start [<\u6587\u4EF6>]\n\t\u6307\u5B9A <\u6587\u4EF6> \u7684\u5185\u5BB9\u5C06\u6210\u4E3A\u9ED8\u8BA4\u542F\u52A8\u7247\u6BB5\u548C\u547D\u4EE4\u3002\n\n/retain feedback [<\u6A21\u5F0F>]\n\t\u8BBE\u7F6E\u7528\u4E8E\u63CF\u8FF0\u4E3A\u6240\u8F93\u5165\u7247\u6BB5\u548C\u547D\u4EE4\u663E\u793A\u7684\u53CD\u9988\u7684\u53CD\u9988\u6A21\u5F0F\u3002\n\n/retain mode <\u6A21\u5F0F>\n\t\u521B\u5EFA\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F, \u53EF\u4EE5\u9009\u62E9\u4ECE\u73B0\u6709\u6A21\u5F0F\u590D\u5236\u3002\n\n\u8981\u83B7\u53D6\u6709\u5173\u5176\u4E2D\u4E00\u4E2A\u683C\u5F0F\u7684\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u5BF9\u6307\u5B9A\u7684\u683C\u5F0F\u4F7F\u7528 /help\u3002\n\u4F8B\u5982:   /help /retain feedback
+help.set =\u8BBE\u7F6E jshell \u914D\u7F6E\u4FE1\u606F, \u5305\u62EC:\n\u8981\u4F7F\u7528\u7684\u5916\u90E8\u7F16\u8F91\u5668, \u8981\u4F7F\u7528\u7684\u542F\u52A8\u5B9A\u4E49, \u65B0\u7684\u53CD\u9988\u6A21\u5F0F,\n\u547D\u4EE4\u63D0\u793A\u7B26, \u8981\u4F7F\u7528\u7684\u53CD\u9988\u6A21\u5F0F\u6216\u8F93\u51FA\u7684\u683C\u5F0F\u3002\n\n/set editor [-wait] <\u547D\u4EE4> <\u53EF\u9009\u53C2\u6570>...\n\t\u6307\u5B9A\u8981\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4\u3002\n\t<\u547D\u4EE4> \u662F\u4E0E\u64CD\u4F5C\u7CFB\u7EDF\u76F8\u5173\u7684\u5B57\u7B26\u4E32\u3002\n\n/set start <\u6587\u4EF6>\n\t\u6307\u5B9A <\u6587\u4EF6> \u7684\u5185\u5BB9\u5C06\u6210\u4E3A\u9ED8\u8BA4\u542F\u52A8\u7247\u6BB5\u548C\u547D\u4EE4\u3002\n\n/set feedback <\u6A21\u5F0F>\n\t\u8BBE\u7F6E\u7528\u4E8E\u63CF\u8FF0\u4E3A\u6240\u8F93\u5165\u7247\u6BB5\u548C\u547D\u4EE4\u663E\u793A\u7684\u53CD\u9988\u7684\u53CD\u9988\u6A21\u5F0F\u3002\n\n/set mode <\u6A21\u5F0F> [<\u65E7\u6A21\u5F0F>] -command|-quiet|-delete\n\t\u521B\u5EFA\u6216\u66F4\u65B0\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F, \u53EF\u4EE5\u9009\u62E9\u4ECE\u73B0\u6709\u6A21\u5F0F\u590D\u5236\u3002\n\n/set prompt <\u6A21\u5F0F> "<\u63D0\u793A>" "<\u66F4\u591A\u63D0\u793A>"\n\t\u8BBE\u7F6E\u4E3A\u7ED9\u5B9A\u53CD\u9988\u6A21\u5F0F\u663E\u793A\u7684\u63D0\u793A\u7B26\u3002\n\n/set truncation <\u6A21\u5F0F> <\u957F\u5EA6> <\u9009\u62E9\u5668>...\n\t\u8BBE\u7F6E\u663E\u793A\u503C\u7684\u6700\u5927\u957F\u5EA6\u3002\n\n/set format <\u6A21\u5F0F> <\u5B57\u6BB5> "<\u683C\u5F0F>" <\u9009\u62E9\u5668>...\n\t\u901A\u8FC7\u8BBE\u7F6E\u5F53\u9009\u62E9\u5668\u5339\u914D\u65F6\u5B57\u6BB5\u7684\u683C\u5F0F\u6765\u914D\u7F6E\u53CD\u9988\u6A21\u5F0F\u3002\n\n/set\n\t\u4EE5 /set \u547D\u4EE4\u5F62\u5F0F\u663E\u793A\u7F16\u8F91\u5668, \u542F\u52A8\u548C\u53CD\u9988\u8BBE\u7F6E\u3002\n\t\u8981\u663E\u793A\u4EE5\u4E0A\u4EFB\u610F\u9879\u7684\u8BBE\u7F6E, \u8BF7\u5FFD\u7565 set \u503C\u3002\n\n\u8981\u83B7\u53D6\u6709\u5173\u5176\u4E2D\u4E00\u4E2A\u683C\u5F0F\u7684\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u5BF9\u6307\u5B9A\u7684\u683C\u5F0F\u4F7F\u7528 /help\u3002\n\u4F8B\u5982:   /help /set format
 
 help.quest.summary = \u83B7\u53D6 jshell \u7684\u76F8\u5173\u4FE1\u606F
 help.quest.args = [<command>|<subject>]
@@ -229,27 +234,22 @@
 help.shortcuts.summary = \u5FEB\u6377\u65B9\u5F0F\u7684\u8BF4\u660E
 help.shortcuts =\u652F\u6301\u7684\u5FEB\u6377\u65B9\u5F0F\u5305\u62EC:\n\n<tab>\n\t\t\u5728\u8F93\u5165 Java \u6807\u8BC6\u7B26, jshell \u547D\u4EE4\u6216 jshell\n\t\t\u547D\u4EE4\u53C2\u6570 (\u5728\u67D0\u4E9B\u60C5\u51B5\u4E0B) \u7684\u524D\u51E0\u4E2A\u5B57\u6BCD\u540E,\n\t\t\u6309 <tab> \u952E\u53EF\u4EE5\u5B8C\u6210\u8F93\u5165\u3002\n\t\t\u5982\u679C\u6709\u591A\u4E2A\u8F93\u5165\u63D0\u793A, \u5219\u663E\u793A\u53EF\u80FD\u7684\u8F93\u5165\u63D0\u793A\u3002\n\nShift-<tab>\n\t\t\u5728\u65B9\u6CD5\u6216\u6784\u9020\u5668\u8C03\u7528\u7684\u540D\u79F0\u548C\u5DE6\u62EC\u53F7\u540E\u9762,\n\t\t\u6309\u4F4F <shift> \u952E\u5E76\u6309 <tab> \u53EF\u67E5\u770B\u6240\u6709\n\t\t\u5339\u914D\u7684\u65B9\u6CD5/\u6784\u9020\u5668\u7684\u63D0\u8981\u3002\n\n<fix-shortcut> v\n\t\t\u5728\u5B8C\u6574\u7684\u8868\u8FBE\u5F0F\u540E\u9762, \u6309 "<fix-shortcut> v" \u53EF\u4EE5\u5F15\u5165\u65B0\u7684\u53D8\u91CF,\n\t\t\u5176\u7C7B\u578B\u57FA\u4E8E\u8868\u8FBE\u5F0F\u7684\u7C7B\u578B\u3002\n\t\t"<fix-shortcut>" \u53EF\u4EE5\u662F Alt-F1 \u6216 Alt-Enter, \u5177\u4F53\u53D6\u51B3\u4E8E\u5E73\u53F0\u3002\n\n<fix-shortcut> i\n\t\t\u5728\u4E0D\u53EF\u89E3\u6790\u7684\u6807\u8BC6\u7B26\u540E\u9762, \u6309 "<fix-shortcut> i", \u6B64\u65F6 jshell \u5C06\u4F1A\n\t\t\u6839\u636E\u6307\u5B9A\u7C7B\u8DEF\u5F84\u7684\u5185\u5BB9\u63D0\u8BAE\u53EF\u80FD\u7684\u5168\u9650\u5B9A\u540D\u79F0\u3002\n\t\t"<fix-shortcut>" \u53EF\u4EE5\u662F Alt-F1 \u6216 Alt-Enter, \u5177\u4F53\u53D6\u51B3\u4E8E\u5E73\u53F0\u3002
 
-help.set.format = \u8BBE\u7F6E\u7528\u4E8E\u62A5\u544A\u7247\u6BB5\u4E8B\u4EF6\u7684\u683C\u5F0F\u3002\n\n\t/set format <\u6A21\u5F0F> <\u5B57\u6BB5> "<\u683C\u5F0F>" <\u9009\u62E9\u5668>...\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0 -- \u8BF7\u53C2\u9605 '/help /set mode'\u3002\n\u5176\u4E2D <\u5B57\u6BB5> \u662F\u8981\u5B9A\u4E49\u7684\u4E0A\u4E0B\u6587\u7279\u5B9A\u683C\u5F0F\u7684\u540D\u79F0\u3002\n\u5176\u4E2D <\u683C\u5F0F> \u662F\u4E00\u4E2A\u5E26\u5F15\u53F7\u7684\u5B57\u7B26\u4E32, \u8BE5\u5B57\u7B26\u4E32\u5C06\u4E3A\n\u5B57\u6BB5\u7684\u503C (\u5982\u679C\u9009\u62E9\u5668\u5339\u914D, \u6216\u8005\u6CA1\u6709\u4EFB\u4F55\u9009\u62E9\u5668)\u3002\n\u5728\u4F7F\u7528\u683C\u5F0F\u65F6, \u7528\u5927\u62EC\u53F7\u62EC\u8D77\u7684\u5B57\u6BB5\u540D\u5C06\u4F1A\u5728\u76F8\u5E94\u65F6\u95F4\n\u4F7F\u7528\u5B57\u6BB5\u503C\u66FF\u6362\u3002\u8FD9\u4E9B\u5B57\u6BB5\u53EF\u80FD\u5DF2\u4F7F\u7528\u6B64\u547D\u4EE4\u5B9A\u4E49, \n\u4E5F\u53EF\u80FD\u662F\u7279\u5B9A\u4E8E\u4E0A\u4E0B\u6587\u7684\u4EE5\u4E0B\u9884\u5B9A\u4E49\u5B57\u6BB5\u4E4B\u4E00:\n\t{name}       == \u540D\u79F0, \u4F8B\u5982: \u53D8\u91CF\u7684\u540D\u79F0, ...\n\t{type}       == \u7C7B\u578B\u540D\u79F0\u3002\u53D8\u91CF\u6216\u8868\u8FBE\u5F0F\u7684\u7C7B\u578B,\n\t\t\t\u65B9\u6CD5\u7684\u53C2\u6570\u7C7B\u578B\n\t{value}      == \u8868\u8FBE\u5F0F\u6216\u53D8\u91CF\u521D\u59CB\u5316\u7684\u7ED3\u679C\u503C\n\t{unresolved} == \u672A\u89E3\u6790\u5F15\u7528\u7684\u5217\u8868\n\t{errors}     == \u53EF\u6062\u590D\u9519\u8BEF\u7684\u5217\u8868 (\u53EA\u5728\u5904\u7406\n\t\t\t"display" \u5B57\u6BB5\u671F\u95F4)\n\t{err}        == \u65E0\u683C\u5F0F\u7684\u9519\u8BEF\u884C (\u53EA\u5728\u5904\u7406\n\t\t\t"errorline" \u5B57\u6BB5\u671F\u95F4)\n\u8BE5\u5DE5\u5177\u8BBF\u95EE\u4EE5\u4E0B\u5B57\u6BB5\u6765\u786E\u5B9A\u6240\u663E\u793A\u7684\u53CD\u9988:\n\t{display}    == \u4E3A\u7247\u6BB5\u4E8B\u4EF6\u663E\u793A\u7684\u6D88\u606F\n\t{errorline}  == "errors" \u5B57\u6BB5\u4E2D\u7684\u4E00\u4E2A\u9519\u8BEF\u884C\u7684\u683C\u5F0F\n\t{pre}        == \u53CD\u9988\u524D\u7F00 (\u4F5C\u4E3A\u547D\u4EE4\u53CD\u9988\u7684\u5F00\u5934)\n\t{post}       == \u53CD\u9988\u540E\u7F00 (\u4F5C\u4E3A\u547D\u4EE4\u53CD\u9988\u7684\u7ED3\u5C3E)\n\t{errorpre}   == \u9519\u8BEF\u524D\u7F00 (\u4F5C\u4E3A\u9519\u8BEF\u53CD\u9988\u7684\u5F00\u5934)\n\t{errorpost}  == \u9519\u8BEF\u540E\u7F00 (\u4F5C\u4E3A\u9519\u8BEF\u53CD\u9988\u7684\u7ED3\u5C3E)\n\u8FD9\u4E9B\u5B57\u6BB5\u5177\u6709\u9ED8\u8BA4\u8BBE\u7F6E (\u53EF\u8986\u76D6)\u3002\n\u5176\u4E2D <selector> \u662F\u5E94\u7528\u683C\u5F0F\u7684\u4E0A\u4E0B\u6587\u3002\n\u9009\u62E9\u5668\u7ED3\u6784\u662F\u4E00\u4E2A\u7531\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u6784\u6210\u7684\u5217\u8868, \u4F7F\u7528\u8FDE\u5B57\u7B26\u5206\u9694\u3002\n\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u662F\u5355\u4E2A\u9009\u62E9\u5668\u7C7B\u578B\u7684\u503C\u7684\u5217\u8868, \u4F7F\u7528\u9017\u53F7\u5206\u9694\u3002\n\u5982\u679C\u6BCF\u4E2A\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u5339\u914D, \u5219\u9009\u62E9\u5668\u5339\u914D; \u5982\u679C\u5176\u4E2D\u67D0\u4E2A\u503C\n\u5339\u914D, \u5219\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u5339\u914D\u3002\n\ncase \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u7247\u6BB5\u7684\u7C7B\u578B\u3002\u503C\u5305\u62EC:\n\timport     -- \u5BFC\u5165\u58F0\u660E\n\tclass      -- \u7C7B\u58F0\u660E\n\tinterface  -- \u63A5\u53E3\u58F0\u660E\n\tenum       -- \u679A\u4E3E\u58F0\u660E\n\tannotation -- \u6CE8\u91CA\u63A5\u53E3\u58F0\u660E\n\tmethod     -- \u65B9\u6CD5\u58F0\u660E -- \u6CE8: {type}==parameter-types\n\tvardecl    -- \u4E0D\u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\tvardecl    -- \u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\texpression -- \u8868\u8FBE\u5F0F -- \u6CE8: {name}==scratch-variable-name\n\tvarvalue   -- \u53D8\u91CF\u503C\u8868\u8FBE\u5F0F\n\tassignment -- \
-\u5206\u914D\u53D8\u91CF\n\tstatement  -- \u8BED\u53E5\n\u64CD\u4F5C\u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u5BF9\u7247\u6BB5\u6267\u884C\u7684\u64CD\u4F5C\u3002\u503C\u5305\u62EC:\n\tadded     -- \u7247\u6BB5\u5DF2\u6DFB\u52A0\n\tmodified  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u4FEE\u6539\n\treplaced  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u66FF\u6362\u4E3A\u65B0\u7247\u6BB5\n\toverwrote -- \u73B0\u6709\u7247\u6BB5\u5DF2\u8986\u76D6\n\tdropped   -- \u7247\u6BB5\u5DF2\u5220\u9664\n\tused      -- \u7247\u6BB5\u5728\u4E0D\u80FD\u4F7F\u7528\u7684\u65F6\u5019\u5DF2\u88AB\u4F7F\u7528\nwhen-did-it-occur \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u8FD9\u662F\u76F4\u63A5\u64CD\u4F5C\u8FD8\u662F\u95F4\u63A5\u64CD\u4F5C\u3002\u503C\u5305\u62EC:\n\tprimary -- \u8F93\u5165\u7684\u7247\u6BB5\n\tupdate  -- \u5BF9\u76F8\u5173\u7247\u6BB5\u7684\u66F4\u65B0\nresolution-state \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u7247\u6BB5\u7684\u89E3\u6790/\u5B9A\u4E49\u72B6\u6001\u3002\u503C\u5305\u62EC:\n\tok         -- \u5DF2\u6B63\u786E\u89E3\u6790\n\tdefined    -- \u5DF2\u5B9A\u4E49, \u4F46\u5B58\u5728\u53EF\u6062\u590D\u7684\u672A\u89E3\u6790\u5F15\u7528\n\tnotdefined -- \u7531\u4E8E\u5B58\u5728\u53EF\u6062\u590D\u7684\u672A\u89E3\u6790\u5F15\u7528\u800C\u672A\u5B9A\u4E49\nunresolved-count \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u672A\u89E3\u6790\u5F15\u7528\u7684\u6570\u91CF\u3002\u503C\u5305\u62EC:\n\tunresolved0 -- \u4E0D\u5B58\u5728\u672A\u89E3\u6790\u7684\u540D\u79F0\n\tunresolved1 -- \u4E00\u4E2A\u540D\u79F0\u672A\u89E3\u6790\n\tunresolved2 -- \u4E24\u4E2A\u6216\u66F4\u591A\u540D\u79F0\u672A\u89E3\u6790\nerrors-count \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u9519\u8BEF\u7684\u6570\u91CF\u3002\u503C\u5305\u62EC:\n\terror0 -- \u65E0\u9519\u8BEF\n\terror1 -- \u4E00\u4E2A\u9519\u8BEF\n\terror2 -- \u4E24\u4E2A\u6216\u66F4\u591A\u9519\u8BEF\n\n\u793A\u4F8B:\n\t/set format myformat action '\u5DF2\u521B\u5EFA' added-primary\n\t/set format myformat action '\u66F4\u65B0\u5DF2\u66FF\u6362' replaced-update\n\t/set format myformat display '{pre}{action} \u7C7B {name}{post}' class-ok\n\t/set format myformat display '{pre}{action} \u53D8\u91CF {name}, \u91CD\u7F6E\u4E3A\u7A7A\u503C{post}' replaced-vardecl,varinit-ok-update\n\n\u8BF7\u6CE8\u610F, \u67D0\u4E2A\u5B57\u6BB5\u7684\u540E\u7EED\u9009\u62E9\u5668\u53EF\u80FD\u4F1A\u8986\u76D6\u90E8\u5206\u6216\u5168\u90E8\u4EE5\u524D\u4F7F\u7528\u7684\u9009\u62E9\u5668 -- \u91C7\u7528\u6700\u540E\u4E00\u4E2A\u9009\u62E9\u5668\n
-
-help.set.truncation = \u8BBE\u7F6E\u663E\u793A\u503C\u7684\u6700\u5927\u957F\u5EA6\u3002\n\n\t/set truncation <\u6A21\u5F0F> <\u957F\u5EA6> <\u9009\u62E9\u5668>...\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0 -- \u8BF7\u53C2\u9605 '/help /set mode'\u3002\n<\u957F\u5EA6> \u662F\u65E0\u7B26\u53F7\u6574\u6570, \u8868\u793A\u6700\u5927\u957F\u5EA6\u3002\n<\u683C\u5F0F> \u662F\u5F15\u53F7\u62EC\u8D77\u7684\u5B57\u7B26\u4E32, \u8BE5\u5B57\u7B26\u4E32\u5C06\u4E3A\u5B57\u6BB5\u7684\u503C\n<\u9009\u62E9\u5668> \u53EA\u6709\u5728\u60A8\u5E0C\u671B\u6839\u636E\u4E0A\u4E0B\u6587\u5FAE\u8C03\u503C\u622A\u65AD\u957F\u5EA6\u65F6\u624D\u9700\u8981,\n<\u9009\u62E9\u5668> \u662F\u5728\u5176\u4E2D\u5E94\u7528\u622A\u65AD\u7684\u4E0A\u4E0B\u6587\u3002\n\u9009\u62E9\u5668\u7ED3\u6784\u662F\u4E00\u4E2A\u8FDE\u5B57\u7B26\u5206\u9694\u7684\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u3002\n\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u662F\u4E00\u4E2A\u5305\u542B\u67D0\u79CD\u9009\u62E9\u5668\u7C7B\u578B\u7684\u503C\u7684\u9017\u53F7\u5206\u9694\u5217\u8868\u3002\n\u9009\u62E9\u5668\u5728\u6240\u6709\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u5339\u914D\u65F6\u5339\u914D; \u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\n\u5219\u5728\u5176\u4E2D\u4E00\u4E2A\u503C\u5339\u914D\u65F6\u5339\u914D\u3002\n\n\u4E0B\u9762\u662F\u7528\u4E8E\u622A\u65AD\u7684\u76F8\u5173\u9009\u62E9\u5668\u7C7B\u578B\u3002\n\ncase \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u7247\u6BB5\u7684\u7C7B\u578B\u3002\u503C\u5305\u62EC:\n\tvardecl    -- \u4E0D\u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\tvarinit    -- \u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\texpression -- \u8868\u8FBE\u5F0F -- \u6CE8: {name}==\u6682\u5B58\u53D8\u91CF\u540D\u79F0\n\tvarvalue   -- \u53D8\u91CF\u503C\u8868\u8FBE\u5F0F\n\tassignment -- \u5206\u914D\u53D8\u91CF\n\t\u64CD\u4F5C\u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u5BF9\u7247\u6BB5\u6267\u884C\u7684\u64CD\u4F5C\u3002\u503C\u5305\u62EC:\n\tadded     -- \u7247\u6BB5\u5DF2\u6DFB\u52A0\n\tmodified  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u4FEE\u6539\n\treplaced  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u66FF\u6362\u4E3A\u65B0\u7247\u6BB5\n\u793A\u4F8B:\n\t/set trunc mymode 80\n\t/set truncation mymode 45 expression\n\t/set truncation mymode 0 vardecl-modified,replaced\n\n\u8BF7\u6CE8\u610F, \u67D0\u4E2A\u5B57\u6BB5\u7684\u540E\u7EED\u9009\u62E9\u5668\u53EF\u80FD\u4F1A\u8986\u76D6\u90E8\u5206\u6216\u5168\u90E8\u4EE5\u524D\u4F7F\u7528\u7684\u9009\u62E9\u5668 -- \u91C7\u7528\u6700\u540E\u4E00\u4E2A\u9009\u62E9\u5668\n
+help.set._retain = '-retain' \u9009\u9879\u4FDD\u5B58\u8BBE\u7F6E\u4EE5\u4FBF\u5728\u5C06\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u3002\n\u53EF\u4EE5\u5728 /set \u7684\u4EE5\u4E0B\u683C\u5F0F\u4E2D\u4F7F\u7528 -retain \u9009\u9879:\n\n\t/set editor -retain\n\t/set start -retain\n\t/set feedback -retain\n\t/set mode -retain\n\n\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u53C2\u9605\u8FD9\u4E9B\u547D\u4EE4 -- \u4F8B\u5982, /help /set editor
 
-help.set.feedback = \u8BBE\u7F6E\u7528\u4E8E\u63CF\u8FF0\u4E3A\u6240\u8F93\u5165\u7247\u6BB5\u548C\u547D\u4EE4\u663E\u793A\u7684\u53CD\u9988\u7684\u53CD\u9988\u6A21\u5F0F\u3002\n\n\t/set feedback <\u6A21\u5F0F>\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n\u60A8\u53EF\u4EE5\u4F7F\u7528\u8DB3\u591F\u591A\u7684\u5B57\u6BCD\u6765\u63D0\u4F9B\u552F\u4E00\u7684\u540D\u79F0\u3002\n\u53EF\u4EE5\u6DFB\u52A0\u7528\u6237\u5B9A\u4E49\u7684\u6A21\u5F0F, \u5177\u4F53\u8BF7\u53C2\u9605 '/help /set mode'\n\u5F53\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F:\n
+help.set.format = \u8BBE\u7F6E\u7528\u4E8E\u62A5\u544A\u7247\u6BB5\u4E8B\u4EF6\u7684\u683C\u5F0F\uFF1A\n\n\t/set format <\u6A21\u5F0F> <\u5B57\u6BB5> "<\u683C\u5F0F>" <\u9009\u62E9\u5668>...\n\n\u663E\u793A\u683C\u5F0F\u8BBE\u7F6E:\n\n\t/set format [<\u6A21\u5F0F> [<\u5B57\u6BB5>]]\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0 -- \u8BF7\u53C2\u9605 '/help /set mode'\u3002\n\u5176\u4E2D <\u5B57\u6BB5> \u662F\u8981\u5B9A\u4E49\u7684\u4E0A\u4E0B\u6587\u7279\u5B9A\u683C\u5F0F\u7684\u540D\u79F0\u3002\n\u5176\u4E2D <\u683C\u5F0F> \u662F\u4E00\u4E2A\u5E26\u5F15\u53F7\u7684\u5B57\u7B26\u4E32, \u8BE5\u5B57\u7B26\u4E32\u5C06\u4E3A\n\u5B57\u6BB5\u7684\u503C (\u5982\u679C\u9009\u62E9\u5668\u5339\u914D, \u6216\u8005\u6CA1\u6709\u4EFB\u4F55\u9009\u62E9\u5668)\u3002\n\u5728\u4F7F\u7528\u683C\u5F0F\u65F6, \u7528\u5927\u62EC\u53F7\u62EC\u8D77\u7684\u5B57\u6BB5\u540D\u5C06\u4F1A\u5728\u76F8\u5E94\u65F6\u95F4\n\u4F7F\u7528\u5B57\u6BB5\u503C\u66FF\u6362\u3002\u8FD9\u4E9B\u5B57\u6BB5\u53EF\u80FD\u5DF2\u4F7F\u7528\u6B64\u547D\u4EE4\u5B9A\u4E49, \n\u4E5F\u53EF\u80FD\u662F\u7279\u5B9A\u4E8E\u4E0A\u4E0B\u6587\u7684\u4EE5\u4E0B\u9884\u5B9A\u4E49\u5B57\u6BB5\u4E4B\u4E00:\n\t{name}       == \u540D\u79F0, \u4F8B\u5982: \u53D8\u91CF\u7684\u540D\u79F0, ...\n\t{type}       == \u7C7B\u578B\u540D\u79F0\u3002\u53D8\u91CF\u6216\u8868\u8FBE\u5F0F\u7684\u7C7B\u578B,\n\t\t\t\u65B9\u6CD5\u7684\u53C2\u6570\u7C7B\u578B\n\t{value}      == \u8868\u8FBE\u5F0F\u6216\u53D8\u91CF\u521D\u59CB\u5316\u7684\u7ED3\u679C\u503C\n\t{unresolved} == \u672A\u89E3\u6790\u5F15\u7528\u7684\u5217\u8868\n\t{errors}     == \u53EF\u6062\u590D\u9519\u8BEF\u7684\u5217\u8868 (\u53EA\u5728\u5904\u7406\n\t\t\t"display" \u5B57\u6BB5\u671F\u95F4)\n\t{err}        == \u65E0\u683C\u5F0F\u7684\u9519\u8BEF\u884C (\u53EA\u5728\u5904\u7406\n\t\t\t"errorline" \u5B57\u6BB5\u671F\u95F4)\n\u8BE5\u5DE5\u5177\u8BBF\u95EE\u4EE5\u4E0B\u5B57\u6BB5\u6765\u786E\u5B9A\u6240\u663E\u793A\u7684\u53CD\u9988:\n\t{display}    == \u4E3A\u7247\u6BB5\u4E8B\u4EF6\u663E\u793A\u7684\u6D88\u606F\n\t{errorline}  == "errors" \u5B57\u6BB5\u4E2D\u7684\u4E00\u4E2A\u9519\u8BEF\u884C\u7684\u683C\u5F0F\n\t{pre}        == \u53CD\u9988\u524D\u7F00 (\u4F5C\u4E3A\u547D\u4EE4\u53CD\u9988\u7684\u5F00\u5934)\n\t{post}       == \u53CD\u9988\u540E\u7F00 (\u4F5C\u4E3A\u547D\u4EE4\u53CD\u9988\u7684\u7ED3\u5C3E)\n\t{errorpre}   == \u9519\u8BEF\u524D\u7F00 (\u4F5C\u4E3A\u9519\u8BEF\u53CD\u9988\u7684\u5F00\u5934)\n\t{errorpost}  == \u9519\u8BEF\u540E\u7F00 (\u4F5C\u4E3A\u9519\u8BEF\u53CD\u9988\u7684\u7ED3\u5C3E)\n\u8FD9\u4E9B\u5B57\u6BB5\u5177\u6709\u9ED8\u8BA4\u8BBE\u7F6E (\u53EF\u8986\u76D6)\u3002\n\u5176\u4E2D <selector> \u662F\u5E94\u7528\u683C\u5F0F\u7684\u4E0A\u4E0B\u6587\u3002\n\u9009\u62E9\u5668\u7ED3\u6784\u662F\u4E00\u4E2A\u7531\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u6784\u6210\u7684\u5217\u8868, \u4F7F\u7528\u8FDE\u5B57\u7B26\u5206\u9694\u3002\n\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u662F\u5355\u4E2A\u9009\u62E9\u5668\u7C7B\u578B\u7684\u503C\u7684\u5217\u8868, \u4F7F\u7528\u9017\u53F7\u5206\u9694\u3002\n\u5982\u679C\u6BCF\u4E2A\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u5339\u914D, \u5219\u9009\u62E9\u5668\u5339\u914D; \u5982\u679C\u5176\u4E2D\u67D0\u4E2A\u503C\n\u5339\u914D, \u5219\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u5339\u914D\u3002\n\ncase \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u7247\u6BB5\u7684\u7C7B\u578B\u3002\u503C\u5305\u62EC:\n\timport     -- \u5BFC\u5165\u58F0\u660E\n\tclass      -- \u7C7B\u58F0\u660E\n\tinterface  -- \u63A5\u53E3\u58F0\u660E\n\tenum       -- \u679A\u4E3E\u58F0\u660E\n\tannotation -- \u6CE8\u91CA\u63A5\u53E3\u58F0\u660E\n\tmethod     -- \u65B9\u6CD5\u58F0\u660E -- \u6CE8: {type}==parameter-types\n\tvardecl    -- \u4E0D\u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\tvardecl    -- \u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\texpression -- \u8868\u8FBE\u5F0F -- \u6CE8: \
+{name}==scratch-variable-name\n\tvarvalue   -- \u53D8\u91CF\u503C\u8868\u8FBE\u5F0F\n\tassignment -- \u5206\u914D\u53D8\u91CF\n\tstatement  -- \u8BED\u53E5\n\u64CD\u4F5C\u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u5BF9\u7247\u6BB5\u6267\u884C\u7684\u64CD\u4F5C\u3002\u503C\u5305\u62EC:\n\tadded     -- \u7247\u6BB5\u5DF2\u6DFB\u52A0\n\tmodified  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u4FEE\u6539\n\treplaced  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u66FF\u6362\u4E3A\u65B0\u7247\u6BB5\n\toverwrote -- \u73B0\u6709\u7247\u6BB5\u5DF2\u8986\u76D6\n\tdropped   -- \u7247\u6BB5\u5DF2\u5220\u9664\n\tused      -- \u7247\u6BB5\u5728\u4E0D\u80FD\u4F7F\u7528\u7684\u65F6\u5019\u5DF2\u88AB\u4F7F\u7528\nwhen-did-it-occur \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u8FD9\u662F\u76F4\u63A5\u64CD\u4F5C\u8FD8\u662F\u95F4\u63A5\u64CD\u4F5C\u3002\u503C\u5305\u62EC:\n\tprimary -- \u8F93\u5165\u7684\u7247\u6BB5\n\tupdate  -- \u5BF9\u76F8\u5173\u7247\u6BB5\u7684\u66F4\u65B0\nresolution-state \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u7247\u6BB5\u7684\u89E3\u6790/\u5B9A\u4E49\u72B6\u6001\u3002\u503C\u5305\u62EC:\n\tok         -- \u5DF2\u6B63\u786E\u89E3\u6790\n\tdefined    -- \u5DF2\u5B9A\u4E49, \u4F46\u5B58\u5728\u53EF\u6062\u590D\u7684\u672A\u89E3\u6790\u5F15\u7528\n\tnotdefined -- \u7531\u4E8E\u5B58\u5728\u53EF\u6062\u590D\u7684\u672A\u89E3\u6790\u5F15\u7528\u800C\u672A\u5B9A\u4E49\nunresolved-count \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u672A\u89E3\u6790\u5F15\u7528\u7684\u6570\u91CF\u3002\u503C\u5305\u62EC:\n\tunresolved0 -- \u4E0D\u5B58\u5728\u672A\u89E3\u6790\u7684\u540D\u79F0\n\tunresolved1 -- \u4E00\u4E2A\u540D\u79F0\u672A\u89E3\u6790\n\tunresolved2 -- \u4E24\u4E2A\u6216\u66F4\u591A\u540D\u79F0\u672A\u89E3\u6790\nerrors-count \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u9519\u8BEF\u7684\u6570\u91CF\u3002\u503C\u5305\u62EC:\n\terror0 -- \u65E0\u9519\u8BEF\n\terror1 -- \u4E00\u4E2A\u9519\u8BEF\n\terror2 -- \u4E24\u4E2A\u6216\u66F4\u591A\u9519\u8BEF\n\n\u793A\u4F8B:\n\t/set format myformat action '\u5DF2\u521B\u5EFA' added-primary\n\t/set format myformat action '\u66F4\u65B0\u5DF2\u66FF\u6362' replaced-update\n\t/set format myformat display '{pre}{action} \u7C7B {name}{post}' class-ok\n\t/set format myformat display '{pre}{action} \u53D8\u91CF {name}, \u91CD\u7F6E\u4E3A\u7A7A\u503C{post}' replaced-vardecl,varinit-ok-update\n\n\u8BF7\u6CE8\u610F, \u67D0\u4E2A\u5B57\u6BB5\u7684\u540E\u7EED\u9009\u62E9\u5668\u53EF\u80FD\u4F1A\u8986\u76D6\u90E8\u5206\u6216\u5168\u90E8\u4EE5\u524D\u4F7F\u7528\u7684\u9009\u62E9\u5668 -- \u91C7\u7528\u6700\u540E\u4E00\u4E2A\u9009\u62E9\u5668\n\n\u4E0D\u5E26 <\u683C\u5F0F> \u7684\u683C\u5F0F\u663E\u793A\u5F53\u524D\u683C\u5F0F\u8BBE\u7F6E\u3002\n\u6307\u5B9A <\u6A21\u5F0F> \u65F6, \u5C06\u4EC5\u663E\u793A\u8BE5\u6A21\u5F0F\u7684\u683C\u5F0F\u8BBE\u7F6E\u3002\n\u540C\u65F6\u6307\u5B9A <\u6A21\u5F0F> \u548C <\u5B57\u6BB5> \u65F6, \u5C06\u4EC5\u663E\u793A\u8BE5\u6A21\u5F0F\u548C\u5B57\u6BB5\u7684\n\u683C\u5F0F\u8BBE\u7F6E\u3002\u793A\u4F8B:\n\t/set format myformat\n\u663E\u793A\u6A21\u5F0F myformat \u7684\u683C\u5F0F\u8BBE\u7F6E\n
 
-help.set.mode = \u521B\u5EFA\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F, \u4E5F\u53EF\u4EE5\u9009\u62E9\u4ECE\u73B0\u6709\u6A21\u5F0F\u590D\u5236\u3002\n\n\t/set mode <\u6A21\u5F0F> [<\u65E7\u6A21\u5F0F>] [-command|-quiet|-delete]\n\n\u5176\u4E2D <\u65B0\u6A21\u5F0F> \u662F\u60A8\u5E0C\u671B\u521B\u5EFA\u7684\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n\u800C <\u65E7\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n\u5982\u679C\u5B58\u5728 <\u65E7\u6A21\u5F0F>, \u5219\u5176\u8BBE\u7F6E\u5C06\u590D\u5236\u5230\u65B0\u6A21\u5F0F\u3002\n'-command' \u4E0E '-quiet' \u51B3\u5B9A\u4E86\u662F\u5426\u663E\u793A\u4FE1\u606F\u6027/\u9A8C\u8BC1\u547D\u4EE4\u53CD\u9988\u3002\n\n\u4E00\u65E6\u521B\u5EFA\u65B0\u6A21\u5F0F, \u5373\u53EF\u4F7F\u7528 '/set format' \u548C '/set prompt' \u8FDB\u884C\u914D\u7F6E\u3002\n\u4F7F\u7528 '/set feedback' \u53EF\u4F7F\u7528\u65B0\u6A21\u5F0F\u3002\n
-help.set.prompt = \u8BBE\u7F6E\u63D0\u793A\u7B26\u3002\u5FC5\u987B\u540C\u65F6\u8BBE\u7F6E\u6B63\u5E38\u63D0\u793A\u548C\u66F4\u591A\u63D0\u793A\u3002\n\n\t/set prompt <\u6A21\u5F0F> "<\u63D0\u793A>" "<\u66F4\u591A\u63D0\u793A>"\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n\u800C <\u63D0\u793A> \u548C <\u66F4\u591A\u63D0\u793A> \u662F\u4F5C\u4E3A\u8F93\u5165\u63D0\u793A\u7B26\u8F93\u51FA\u7684\u5E26\u5F15\u53F7\u7684\u5B57\u7B26\u4E32;\n\u5B83\u4EEC\u5747\u53EF\u9009\u62E9\u6027\u5730\u5305\u542B '%s', \u8BE5\u53D8\u91CF\u5C06\u88AB\u66FF\u6362\u4E3A\u4E0B\u4E00\u4E2A\u7247\u6BB5 id --\n\u8BF7\u6CE8\u610F, \u53EF\u80FD\u65E0\u6CD5\u5411\u6240\u8F93\u5165\u5185\u5BB9\u5206\u914D\u8BE5 id, \u4F8B\u5982\u8FD9\u53EF\u80FD\u662F\u4E00\u4E2A\u9519\u8BEF\u6216\u547D\u4EE4\u3002\n\u66F4\u591A\u63D0\u793A\u5728\u591A\u884C\u7247\u6BB5\u7684\u7B2C\u4E8C\u884C\u4EE5\u53CA\u540E\u7EED\u884C\u4E0A\u4F7F\u7528\u3002\n
+help.set.truncation = \u8BBE\u7F6E\u663E\u793A\u503C\u7684\u6700\u5927\u957F\u5EA6:\n\n\t/set truncation <\u6A21\u5F0F> <\u957F\u5EA6> <\u9009\u62E9\u5668>...\n\n\u663E\u793A\u5F53\u524D\u622A\u65AD\u8BBE\u7F6E:\n\n\t/set truncation [<\u6A21\u5F0F>]\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u540D\u79F0 -- \u8BF7\u53C2\u9605 '/help /set mode'\u3002\n\u800C <\u957F\u5EA6> \u662F\u65E0\u7B26\u53F7\u6574\u6570, \u8868\u793A\u6700\u5927\u957F\u5EA6\u3002\n<\u9009\u62E9\u5668> \u53EA\u6709\u5728\u60A8\u5E0C\u671B\u6839\u636E\u4E0A\u4E0B\u6587\u5FAE\u8C03\u503C\u622A\u65AD\u957F\u5EA6\u65F6\u624D\u9700\u8981,\n<\u9009\u62E9\u5668> \u662F\u5728\u5176\u4E2D\u5E94\u7528\u622A\u65AD\u7684\u4E0A\u4E0B\u6587\u3002\n\u9009\u62E9\u5668\u7ED3\u6784\u662F\u4E00\u4E2A\u8FDE\u5B57\u7B26\u5206\u9694\u7684\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u3002\n\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u662F\u4E00\u4E2A\u5305\u542B\u67D0\u79CD\u9009\u62E9\u5668\u7C7B\u578B\u7684\u503C\u7684\u9017\u53F7\u5206\u9694\u5217\u8868\u3002\n\u9009\u62E9\u5668\u5728\u6240\u6709\u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\u5339\u914D\u65F6\u5339\u914D; \u9009\u62E9\u5668\u7C7B\u578B\u5217\u8868\n\u5219\u5728\u5176\u4E2D\u4E00\u4E2A\u503C\u5339\u914D\u65F6\u5339\u914D\u3002\n\n\u4E0B\u9762\u662F\u7528\u4E8E\u622A\u65AD\u7684\u76F8\u5173\u9009\u62E9\u5668\u7C7B\u578B\u3002\n\ncase \u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u7247\u6BB5\u7684\u7C7B\u578B\u3002\u503C\u5305\u62EC:\n\tvardecl    -- \u4E0D\u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\tvarinit    -- \u5E26\u521D\u59CB\u5316\u7684\u53D8\u91CF\u58F0\u660E\n\texpression -- \u8868\u8FBE\u5F0F -- \u6CE8: {name}==\u6682\u5B58\u53D8\u91CF\u540D\u79F0\n\tvarvalue   -- \u53D8\u91CF\u503C\u8868\u8FBE\u5F0F\n\tassignment -- \u5206\u914D\u53D8\u91CF\n\t\u64CD\u4F5C\u9009\u62E9\u5668\u7C7B\u578B\u63CF\u8FF0\u4E86\u5BF9\u7247\u6BB5\u6267\u884C\u7684\u64CD\u4F5C\u3002\u503C\u5305\u62EC:\n\tadded     -- \u7247\u6BB5\u5DF2\u6DFB\u52A0\n\tmodified  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u4FEE\u6539\n\treplaced  -- \u73B0\u6709\u7247\u6BB5\u5DF2\u66FF\u6362\u4E3A\u65B0\u7247\u6BB5\n\u793A\u4F8B:\n\t/set trunc mymode 80\n\t/set truncation mymode 45 expression\n\t/set truncation mymode 0 vardecl-modified,replaced\n\n\u8BF7\u6CE8\u610F, \u67D0\u4E2A\u5B57\u6BB5\u7684\u540E\u7EED\u9009\u62E9\u5668\u53EF\u80FD\u4F1A\u8986\u76D6\u90E8\u5206\u6216\u5168\u90E8\u4EE5\u524D\u4F7F\u7528\u7684\u9009\u62E9\u5668 -- \u91C7\u7528\u6700\u540E\u4E00\u4E2A\u9009\u62E9\u5668\n\n\u4E0D\u5E26 <\u957F\u5EA6> \u7684\u683C\u5F0F\u663E\u793A\u622A\u65AD\u8BBE\u7F6E\u3002\n\u6307\u5B9A <\u6A21\u5F0F> \u65F6, \u5C06\u4EC5\u663E\u793A\u8BE5\u6A21\u5F0F\u7684\u622A\u65AD\u8BBE\u7F6E\u3002\n\u793A\u4F8B:\n\t/set truncation myformat\n\u663E\u793A\u6A21\u5F0F myformat \u7684\u622A\u65AD\u8BBE\u7F6E\n
 
-help.set.editor =\u6307\u5B9A\u8981\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4\u3002\n\n\t/set editor <\u547D\u4EE4>|-default\n\n<\u547D\u4EE4> \u662F\u4E00\u4E2A\u64CD\u4F5C\u7CFB\u7EDF\u76F8\u5173\u5B57\u7B26\u4E32\u3002\n<\u547D\u4EE4> \u53EF\u4EE5\u5305\u542B\u7528\u7A7A\u683C\u5206\u9694\u7684\u53C2\u6570 (\u4F8B\u5982\u6807\u8BB0)\n\u5728\u4F7F\u7528 /edit \u65F6, \u8981\u7F16\u8F91\u7684\u4E34\u65F6\u6587\u4EF6\u5C06\u4F5C\u4E3A\u6700\u540E\u4E00\u4E2A\u53C2\u6570\u9644\u52A0\u3002\n\u5982\u679C\u6539\u4E3A\u6307\u5B9A -default \u9009\u9879, \u5219\u5C06\u4F7F\u7528\u9ED8\u8BA4\u7684\u5185\u7F6E\u7F16\u8F91\u5668\u3002
+help.set.feedback = \u8BBE\u7F6E\u53CD\u9988\u6A21\u5F0F, \u8BE5\u6A21\u5F0F\u63CF\u8FF0\u4E3A\u6240\u8F93\u5165\u7684\u7247\u6BB5\u548C\u547D\u4EE4\u663E\u793A\u7684\u53CD\u9988:\n\n\t/set feedback [-retain] <\u6A21\u5F0F>\n\n\u4FDD\u7559\u5F53\u524D\u53CD\u9988\u6A21\u5F0F\u4EE5\u4FBF\u5728\u5C06\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528:\n\n\t/set feedback -retain\n\n\u663E\u793A\u53CD\u9988\u6A21\u5F0F\u5E76\u5217\u51FA\u53EF\u7528\u6A21\u5F0F:\n\n\t/set feedback\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u540D\u79F0\u3002\n\u60A8\u53EF\u4EE5\u4F7F\u7528\u8DB3\u591F\u591A\u7684\u5B57\u6BCD\u6765\u63D0\u4F9B\u552F\u4E00\u7684\u540D\u79F0\u3002\n\u53EF\u4EE5\u6DFB\u52A0\u7528\u6237\u5B9A\u4E49\u7684\u6A21\u5F0F, \u5177\u4F53\u8BF7\u53C2\u9605 '/help /set mode'\n\n\u4F7F\u7528 -retain \u9009\u9879\u65F6, \u5C06\u5728\u672C\u6B21\u8FD0\u884C\u548C\u5C06\u6765\u8FD0\u884C jshell \u5DE5\u5177\u65F6\n\u4F7F\u7528\u6B64\u8BBE\u7F6E\u3002\n\n\u4E0D\u5E26 <\u6A21\u5F0F> \u7684\u683C\u5F0F\u6216 -retain \u663E\u793A\u5F53\u524D\u53CD\u9988\u6A21\u5F0F\u548C\u53EF\u7528\u6A21\u5F0F\u3002\n
 
-help.set.start =\u8BBE\u7F6E\u542F\u52A8\u914D\u7F6E -- \u5728\u542F\u52A8\u65F6\u8BFB\u53D6\u7684\u4E00\u7CFB\u5217\u7247\u6BB5\u548C\u547D\u4EE4\u3002\n\n\t/set start <\u6587\u4EF6>|-default|-none\n\n\u5728\u6B64\u4F1A\u8BDD\u4E2D\u4F7F\u7528 /reset \u6216 /reload \u547D\u4EE4\u65F6, \n\u6307\u5B9A <\u6587\u4EF6> \u7684\u5185\u5BB9\u5C06\u6210\u4E3A\u6240\u7528\u7684\u542F\u52A8\u7247\u6BB5\u548C\u547D\u4EE4\u3002\n\u5982\u679C\u6539\u4E3A\u6307\u5B9A -default \u9009\u9879, \u5219\u5C06\u4F7F\u7528\u9884\u5B9A\u4E49\u7684\n\u542F\u52A8\u7247\u6BB5\u3002\n\u5982\u679C\u4F7F\u7528 -none \u9009\u9879, \u5219\u542F\u52A8\u5C06\u4E3A\u7A7A -- \u5C06\u4E0D\u4F7F\u7528\n\u542F\u52A8\u7247\u6BB5\u6216\u547D\u4EE4\u3002\n\u6B64\u547D\u4EE4\u5BF9\u4E8E\u6D4B\u8BD5\u542F\u52A8\u8BBE\u7F6E\u975E\u5E38\u6709\u7528\u3002\u8981\u4FDD\u7559\u8FD9\u4E9B\u5185\u5BB9\n\u4F9B\u4EE5\u540E\u8FD0\u884C jshell \u5DE5\u5177, \u8BF7\u4F7F\u7528\u547D\u4EE4:\n\t/retain start\n
+help.set.mode = \u521B\u5EFA\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F, \u4E5F\u53EF\u4EE5\u9009\u62E9\u4ECE\u73B0\u6709\u6A21\u5F0F\u590D\u5236:\n\n\t/set mode <\u6A21\u5F0F> [<\u65E7\u6A21\u5F0F>] [-command|-quiet|-delete]\n\u4FDD\u7559\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u4EE5\u4FBF\u5728\u5C06\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528:\n\n\t/set mode -retain <\u6A21\u5F0F>\n\n\u5220\u9664\u7528\u6237\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F:\n\n\t/set mode -delete [-retain] <\u6A21\u5F0F>\n\n\u663E\u793A\u53CD\u9988\u6A21\u5F0F\u8BBE\u7F6E:\n\n\t/set mode [<\u6A21\u5F0F>]\n\n\u5176\u4E2D <\u65B0\u6A21\u5F0F> \u662F\u60A8\u5E0C\u671B\u521B\u5EFA\u7684\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n\u800C <\u65E7\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u540D\u79F0\u3002\n\u5982\u679C\u5B58\u5728 <\u65E7\u6A21\u5F0F>, \u5176\u8BBE\u7F6E\u5C06\u4F1A\u590D\u5236\u5230\u65B0\u6A21\u5F0F\u3002\n'-command' \u4E0E '-quiet' \u51B3\u5B9A\u4E86\u662F\u5426\u663E\u793A\u4FE1\u606F\u6027/\u9A8C\u8BC1\u547D\u4EE4\u53CD\u9988\u3002\n\n\u4E00\u65E6\u521B\u5EFA\u65B0\u6A21\u5F0F, \u5373\u53EF\u4F7F\u7528 '/set format', '/set prompt' \u548C '/set truncation'\n\u8FDB\u884C\u914D\u7F6E\u3002\u4F7F\u7528 '/set feedback' \u53EF\u4F7F\u7528\u65B0\u6A21\u5F0F\u3002\n\n\u4F7F\u7528 -retain \u9009\u9879\u65F6, \u5C06\u5728\u672C\u6B21\u8FD0\u884C\u548C\u5C06\u6765\u8FD0\u884C jshell \u5DE5\u5177\u65F6\n\u4F7F\u7528\u8BE5\u6A21\u5F0F (\u5305\u62EC\u5176\u7EC4\u4EF6\u63D0\u793A, \u683C\u5F0F\u548C\u622A\u65AD\u8BBE\u7F6E)\u3002\n\u540C\u65F6\u4F7F\u7528 -retain \u548C -delete \u65F6, \u5C06\u4ECE\u5F53\u524D\u548C\u5C06\u6765\u4F1A\u8BDD\u4E2D\n\u5220\u9664\u8BE5\u6A21\u5F0F\u3002\n\n\u4E0D\u5E26\u9009\u9879\u7684\u683C\u5F0F\u663E\u793A\u6A21\u5F0F\u8BBE\u7F6E\u3002\n\u6307\u5B9A <\u6A21\u5F0F> \u65F6, \u5C06\u4EC5\u663E\u793A\u8BE5\u6A21\u5F0F\u7684\u6A21\u5F0F\u8BBE\u7F6E\u3002\n\u6CE8: \u6A21\u5F0F\u8BBE\u7F6E\u5305\u62EC\u63D0\u793A, \u683C\u5F0F\u548C\u622A\u65AD\u7684\n\u8BBE\u7F6E -- \u56E0\u6B64\u8FD8\u4F1A\u663E\u793A\u8FD9\u4E9B\u8BBE\u7F6E\u3002\n\u793A\u4F8B:\n\t/set mode myformat\n\u663E\u793A\u6A21\u5F0F myformat \u7684\u6A21\u5F0F, \u63D0\u793A, \u683C\u5F0F\u548C\u622A\u65AD\u8BBE\u7F6E\n
 
-help.retain.feedback = \u4FDD\u7559\u4E3A\u6240\u8F93\u5165\u7247\u6BB5\u548C\u547D\u4EE4\u663E\u793A\u7684\u53CD\u9988\u4F7F\u7528\u7684\u53CD\u9988\u6A21\u5F0F\u3002\n\u6B64\u53CD\u9988\u6A21\u5F0F\u5C06\u5728 jshell \u5DE5\u5177\u7684\u6B64\u4F1A\u8BDD\u548C\u672A\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u3002\n\n\t/retain feedback [<\u6A21\u5F0F>]\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n\u60A8\u53EF\u4EE5\u4F7F\u7528\u8DB3\u591F\u591A\u7684\u5B57\u6BCD\u6765\u63D0\u4F9B\u552F\u4E00\u7684\u540D\u79F0\u3002\n\u5982\u679C\u672A\u6307\u5B9A <\u6A21\u5F0F>, \u5219\u6B64\u547D\u4EE4\u4FDD\u7559\u5F53\u524D\u6A21\u5F0F (\u7531\n\u6700\u65B0 /set feedback \u6216 /retain feedback \u547D\u4EE4\u6240\u8BBE\u7F6E)\u3002\n
-help.retain.mode = \u7EE7\u7EED\u4F7F\u7528\u7528\u6237\u5B9A\u4E49\u53CD\u9988\u6A21\u5F0F\u5E76\u4FDD\u7559\u5176\u914D\u7F6E\u3002\n\u6B64\u6A21\u5F0F\u5C06\u5728 jshell \u5DE5\u5177\u7684\u6B64\u4F1A\u8BDD\u548C\u672A\u6765\u4F1A\u8BDD\u4E2D\u53EF\u7528\u3002
-\n\t/retain mode <\u6A21\u5F0F>\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u8981\u4FDD\u7559\u7684\u6A21\u5F0F\u7684\u540D\u79F0\u3002\n<\u6A21\u5F0F> \u5FC5\u987B\u662F\u4EE5\u524D\u5DF2\u4F7F\u7528 /set mode \u521B\u5EFA\u5E76\u6839\u636E\u9700\u8981\n\u4F7F\u7528 /set prompt, /set format \u548C /set truncation \u914D\u7F6E\u7684\u6A21\u5F0F\u3002\n
+help.set.prompt = \u8BBE\u7F6E\u63D0\u793A\u7B26\u3002\u5FC5\u987B\u540C\u65F6\u8BBE\u7F6E\u6B63\u5E38\u63D0\u793A\u548C\u66F4\u591A\u63D0\u793A:\n\n\t/set prompt <\u6A21\u5F0F> "<\u63D0\u793A>" "<\u66F4\u591A\u63D0\u793A>"\n\n\u663E\u793A\u6B63\u5E38\u63D0\u793A\u548C\u66F4\u591A\u63D0\u793A:\n\n\t/set prompt [<\u6A21\u5F0F>]\n\n\u5176\u4E2D <\u6A21\u5F0F> \u662F\u4EE5\u524D\u5B9A\u4E49\u7684\u53CD\u9988\u6A21\u5F0F\u540D\u79F0\u3002\n\u800C <\u63D0\u793A> \u548C <\u66F4\u591A\u63D0\u793A> \u662F\u4F5C\u4E3A\u8F93\u5165\u63D0\u793A\u7B26\u8F93\u51FA\u7684\u5E26\u5F15\u53F7\u7684\u5B57\u7B26\u4E32;\n\u5B83\u4EEC\u5747\u53EF\u9009\u62E9\u6027\u5730\u5305\u542B '%s', \u8BE5\u53D8\u91CF\u5C06\u88AB\u66FF\u6362\u4E3A\u4E0B\u4E00\u4E2A\u7247\u6BB5 ID --\n\u8BF7\u6CE8\u610F, \u53EF\u80FD\u65E0\u6CD5\u5411\u6240\u8F93\u5165\u5185\u5BB9\u5206\u914D\u8BE5 ID, \u4F8B\u5982\u8FD9\u53EF\u80FD\u662F\u4E00\u4E2A\u9519\u8BEF\u6216\u547D\u4EE4\u3002\n\u66F4\u591A\u63D0\u793A\u5728\u591A\u884C\u7247\u6BB5\u7684\u7B2C\u4E8C\u884C\u4EE5\u53CA\u540E\u7EED\u884C\u4E0A\u4F7F\u7528\u3002\n\n\u4E0D\u5E26 <\u63D0\u793A> \u7684\u683C\u5F0F\u663E\u793A\u5F53\u524D\u8BBE\u7F6E\u63D0\u793A\u3002\n\u6307\u5B9A <\u6A21\u5F0F> \u65F6, \u5C06\u4EC5\u663E\u793A\u8BE5\u6A21\u5F0F\u7684\u63D0\u793A\u3002\n\u793A\u4F8B:\n\t/set prompt myformat\n\u663E\u793A\u4E3A\u6A21\u5F0F myformat \u8BBE\u7F6E\u7684\u63D0\u793A\n
 
-help.retain.editor =\u4FDD\u7559\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4\u3002\u5728 jshell \u5DE5\u5177\u7684\u6B64\u4F1A\u8BDD\u548C\n\u672A\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528 /edit \u547D\u4EE4\u65F6\u5C06\u8C03\u7528\u6B64\u547D\u4EE4\u3002\n\n\t/retain editor [<\u547D\u4EE4>|-default]\n\n\u5982\u679C\u6307\u5B9A <\u547D\u4EE4>, \u5219\u5B83\u662F\u4E00\u4E2A\u64CD\u4F5C\u7CFB\u7EDF\u76F8\u5173\u5B57\u7B26\u4E32,\n\u53EF\u4EE5\u5305\u542B\u7528\u7A7A\u683C\u5206\u9694\u7684\u53C2\u6570 (\u4F8B\u5982\u6807\u8BB0)\u3002\u5728\u4F7F\u7528 /edit \u65F6,\n\u8981\u7F16\u8F91\u7684\u4E34\u65F6\u6587\u4EF6\u5C06\u4F5C\u4E3A\u6700\u540E\u4E00\u4E2A\u53C2\u6570\u9644\u52A0\u3002\n\u5982\u679C\u6539\u4E3A\u6307\u5B9A -default \u9009\u9879, \u5219\u5C06\u4F7F\u7528\u9ED8\u8BA4\u7684\u5185\u7F6E\u7F16\u8F91\u5668\u3002\n\u5982\u679C\u672A\u6307\u5B9A\u4EFB\u4F55\u9009\u9879, \u5219\u5C06\u4F7F\u7528\u5728\u4E0A\u4E00\u4E2A /set editor \u6216 /retain editor\n\u547D\u4EE4\u4E2D\u6307\u5B9A\u7684\u7F16\u8F91\u5668\u8BBE\u7F6E\u3002\n\u8BE5\u7F16\u8F91\u5668\u5C06\u4F1A\u4FDD\u7559\u5E76\u7528\u4E8E jshell \u5DE5\u5177\u7684\u6B64\u4F1A\u8BDD\u548C\u672A\u6765\u4F1A\u8BDD\u3002
+help.set.editor =\u6307\u5B9A\u8981\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4:\n\n\t/set editor [-retain] [-wait] <\u547D\u4EE4>\n\n\t/set editor [-retain] -default\n\n\t/set editor [-retain] -delete\n\n\u4FDD\u7559\u5F53\u524D\u7F16\u8F91\u5668\u8BBE\u7F6E\u4EE5\u4FBF\u5728\u5C06\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528:\n\n\t/set editor -retain\n\n\u663E\u793A\u8981\u4E3A /edit \u547D\u4EE4\u542F\u52A8\u7684\u547D\u4EE4:\n\n\t/set editor\n\n<\u547D\u4EE4> \u662F\u4E0E\u64CD\u4F5C\u7CFB\u7EDF\u76F8\u5173\u7684\u5B57\u7B26\u4E32\u3002\n<\u547D\u4EE4> \u53EF\u4EE5\u5305\u542B\u7528\u7A7A\u683C\u5206\u9694\u7684\u53C2\u6570 (\u4F8B\u5982\u6807\u8BB0)\n\n\u5982\u679C\u6307\u5B9A\u4E86 -default \u9009\u9879, \u5C06\u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u7F16\u8F91\u5668\u3002\n\n\u5982\u679C\u6307\u5B9A\u4E86 -delete \u9009\u9879, \u5C06\u5FFD\u7565\u4EE5\u524D\u7684\u8BBE\u7F6E -- \u542F\u52A8\njshell \u5DE5\u5177\u65F6\u5C06\u521D\u59CB\u5316\u7F16\u8F91\u5668\u8BBE\u7F6E\u3002\u5177\u4F53\u6765\u8BF4, \u5982\u679C\u5B58\u5728\n\u4FDD\u7559\u7684\u8BBE\u7F6E, \u5C06\u4F7F\u7528\u4FDD\u7559\u7684\u8BBE\u7F6E (\u9664\u975E\u540C\u65F6\u6307\u5B9A -retain \u548C -delete --\n\u8FD9\u5C06\u5220\u9664\u4FDD\u7559\u7684\u8BBE\u7F6E), \u5982\u679C\u8BBE\u7F6E\u4E86\u4EE5\u4E0B\u67D0\u4E2A\u73AF\u5883\u53D8\u91CF, \n\u5C06\u4F7F\u7528\u5B83: JSHELLEDITOR, VISUAL \u6216 EDITOR (\u6309\u6B64\u987A\u5E8F)\u3002\u5426\u5219\u5C06\u4F7F\u7528\n\u5185\u7F6E\u9ED8\u8BA4\u7F16\u8F91\u5668\u3002\n\n\u5982\u679C\u6307\u5B9A\u4E86 <\u547D\u4EE4>, \u5B83\u5C06\u7528\u4F5C\u5916\u90E8\u7F16\u8F91\u5668\u3002<\u547D\u4EE4>\n\u7531\u7A0B\u5E8F\u53CA\u96F6\u4E2A\u6216\u591A\u4E2A\u7A0B\u5E8F\u53C2\u6570\u7EC4\u6210\u3002\u4F7F\u7528 <\u547D\u4EE4>\n\u65F6, \u8981\u7F16\u8F91\u7684\u4E34\u65F6\u6587\u4EF6\u5C06\u4F5C\u4E3A\u6700\u540E\u4E00\u4E2A\u53C2\u6570\u9644\u52A0\u3002\n\u901A\u5E38, \u7F16\u8F91\u6A21\u5F0F\u5C06\u6301\u7EED\u5230\u9000\u51FA\u5916\u90E8\u7F16\u8F91\u5668\u4E3A\u6B62\u3002\u67D0\u4E9B\u5916\u90E8\u7F16\u8F91\u5668\n\u5C06\u7ACB\u5373\u9000\u51FA (\u4F8B\u5982, \u5982\u679C\u9000\u51FA\u7F16\u8F91\u7A97\u53E3), \u5E94\u4F7F\u7528\u5916\u90E8\u7F16\u8F91\u5668\n\u6807\u8BB0\u963B\u6B62\u7ACB\u5373\u9000\u51FA, \u6216\u8005\u4F7F\u7528 -wait \u9009\u9879\n\u63D0\u793A\u7528\u6237\u6307\u793A\u4F55\u65F6\u5E94\u7ED3\u675F\u7F16\u8F91\u6A21\u5F0F\u3002\n\n\u6CE8: \u5728\u7F16\u8F91\u6A21\u5F0F\u4E0B, \u4E0D\u4F1A\u663E\u793A\u4EFB\u4F55\u547D\u4EE4\u8F93\u5165\u3002\u9000\u51FA\u7F16\u8F91\u6A21\u5F0F\u540E, \n\u5C06\u4E0D\u4F1A\u663E\u793A\u5BF9\u7F16\u8F91\u7684\u7247\u6BB5\u6240\u505A\u7684\u4EFB\u4F55\u66F4\u6539\u3002\n\n\u4F7F\u7528 -retain \u9009\u9879\u65F6, \u5C06\u5728\u672C\u6B21\u8FD0\u884C\u548C\u5C06\u6765\u8FD0\u884C jshell \u5DE5\u5177\u65F6\n\u4F7F\u7528\u8BE5\u8BBE\u7F6E\u3002\n\n\u4E0D\u5E26 <\u547D\u4EE4> \u6216\u9009\u9879\u7684\u683C\u5F0F\u663E\u793A\u7F16\u8F91\u5668\u8BBE\u7F6E\u3002\n
 
-help.retain.start =\u4FDD\u7559\u542F\u52A8\u914D\u7F6E -- \u5728\u542F\u52A8\u65F6\u8BFB\u53D6\u7684\u4E00\u7CFB\u5217\u7247\u6BB5\u548C\n\u547D\u4EE4\u3002\n\n\t/retain start [<\u6587\u4EF6>|-default|-none]\n\n\u5982\u679C\u6307\u5B9A <\u6587\u4EF6>, \u5219\u6307\u5B9A <\u6587\u4EF6> \u7684\u5185\u5BB9\u5C06\u6210\u4E3A\n\u542F\u52A8\u7247\u6BB5\u548C\n\u547D\u4EE4\u3002\n\u5982\u679C\u6539\u4E3A\u6307\u5B9A\u4E86 -default \u9009\u9879, \u5219\u9884\u5B9A\u4E49\u7684\u542F\u52A8\u7247\u6BB5\n\u5C06\u6210\u4E3A\u542F\u52A8\u7247\u6BB5\u3002\n\u5982\u679C\u4F7F\u7528 -none \u9009\u9879, \u5219\u542F\u52A8\u5C06\u4E3A\u7A7A -- \u5C06\u4E0D\u4F7F\u7528\n\u542F\u52A8\u7247\u6BB5\u6216\u547D\u4EE4\u3002\n\u5982\u679C\u672A\u6307\u5B9A\u4EFB\u4F55\u8FD9\u4E9B\u9009\u9879, \u5219\u542F\u52A8\u5C06\u4E3A\u4E0A\u4E00\u6B21\u5728\n''/set start'' \u6216 ''/retain start'' \u547D\u4EE4\u4E2D\u6307\u5B9A\u7684\u5185\u5BB9\u3002\n\u542F\u52A8\u8BBE\u7F6E\u5C06\u4F1A\u4FDD\u7559, \u5E76\u5728\u542F\u52A8\u6216\u91CD\u542F jshell \u5DE5\u5177\u65F6\u4F7F\u7528
+help.set.start =\u8BBE\u7F6E\u542F\u52A8\u914D\u7F6E -- \u542F\u52A8\u65F6\u8BFB\u53D6\u7684\u7247\u6BB5\u548C\u547D\u4EE4\u5E8F\u5217:\n\n\t/set start [-retain] <\u6587\u4EF6>\n\n\t/set start [-retain] -default\n\n\t/set start [-retain] -none\n\n\u4FDD\u7559\u542F\u52A8\u914D\u7F6E\u4EE5\u4FBF\u5728\u5C06\u6765\u4F1A\u8BDD\u4E2D\u4F7F\u7528:\n\n\t/set start -retain\n\n\u663E\u793A\u542F\u52A8\u8BBE\u7F6E:\n\n\t/set start\n\n\u5728\u6B64\u4F1A\u8BDD\u4E2D\u4F7F\u7528 /reset \u6216 /reload \u547D\u4EE4\u65F6, \n\u6307\u5B9A <\u6587\u4EF6> \u7684\u5185\u5BB9\u5C06\u6210\u4E3A\u4F7F\u7528\u7684\u542F\u52A8\u7247\u6BB5\u548C\u547D\u4EE4\u3002\n\u5982\u679C\u6539\u4E3A\u6307\u5B9A -default \u9009\u9879, \u5219\u5C06\u4F7F\u7528\u9884\u5B9A\u4E49\u7684\n\u542F\u52A8\u7247\u6BB5\u3002\n\u5982\u679C\u4F7F\u7528 -none \u9009\u9879, \u5219\u542F\u52A8\u8BBE\u7F6E\u5C06\u4E3A\u7A7A -- \u5C06\u4E0D\u4F7F\u7528\n\u542F\u52A8\u7247\u6BB5\u6216\u547D\u4EE4\u3002\n\u6B64\u547D\u4EE4\u5BF9\u4E8E\u6D4B\u8BD5\u542F\u52A8\u8BBE\u7F6E\u975E\u5E38\u6709\u7528\u3002\u8981\u4FDD\u7559\u8FD9\u4E9B\u5185\u5BB9\n\u4EE5\u4FBF\u5C06\u6765\u8FD0\u884C jshell \u5DE5\u5177\u65F6\u4F7F\u7528, \u8BF7\u4F7F\u7528\u547D\u4EE4:\n\t/set start -retain\n\n\u4F7F\u7528 -retain \u9009\u9879\u65F6, \u5C06\u5728\u672C\u6B21\u8FD0\u884C\u548C\u5C06\u6765\n\u8FD0\u884C jshell \u5DE5\u5177\u65F6\u4F7F\u7528\u8BE5\u8BBE\u7F6E\u3002\n\n\u4E0D\u5E26 <\u6587\u4EF6> \u6216\u9009\u9879\u7684\u683C\u5F0F\u663E\u793A\u542F\u52A8\u8BBE\u7F6E\u3002\n\u6CE8: \u5982\u679C\u542F\u52A8\u8BBE\u7F6E\u6700\u540E\u4E00\u6B21\u662F\u4ECE\u6587\u4EF6\u8BBE\u7F6E\u7684, \u5219\u4F1A\u968F\u6587\u4EF6\u5185\u5BB9 (\u540E\u8DDF 'set start' \u547D\u4EE4) \n\u4E00\u8D77\u663E\u793A\u6B64\u5185\u5BB9\u3002
 
-startup.feedback = /set mode verbose -command    \n\n/set prompt verbose '\\njshell> '   '   ...> '    \n\n/set format verbose pre '|  '    \n/set format verbose post '%n'    \n/set format verbose errorpre '|  '    \n/set format verbose errorpost '%n'    \n\n/set format verbose errorline '{post}{pre}    {err}'    \n\n/set format verbose action '\u5DF2\u521B\u5EFA' added-primary    \n/set format verbose action '\u5DF2\u4FEE\u6539' modified-primary    \n/set format verbose action '\u5DF2\u66FF\u6362' replaced-primary    \n/set format verbose action '\u5DF2\u8986\u76D6' overwrote-primary    \n/set format verbose action '\u5DF2\u5220\u9664' dropped-primary    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u521B\u5EFA' added-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u4FEE\u6539' modified-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u66FF\u6362' replaced-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u8986\u76D6' overwrote-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u5220\u9664' dropped-update    \n\n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u5B9E\u4F8B\u5316\u6216\u8005\u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'   defined-class-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                      defined-interface-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u4F7F\u7528, \u76F4\u81F3'                                  defined-enum,annotation-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                               defined-method-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u5F15\u7528, \u76F4\u81F3'                            notdefined-primary    \n/set format verbose until ' \u5B83\u65E0\u6CD5\u5B9E\u4F8B\u5316\u6216\u8005\u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'          defined-class-update    \n/set format verbose until ' \u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                              defined-interface-update    \n/set format verbose until ' \u5B83\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                                      defined-method-update    \n/set format verbose until ' \u5B83\u65E0\u6CD5\u5F15\u7528, \u76F4\u81F3'                                   notdefined-update    \n\n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E'                                           unresolved1-error0    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E'                                          unresolved2-error0    \n/set format verbose unrerr ' \u6B64\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'                                 unresolved0-error1    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E, \u5E76\u4E14\u6B64\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'     unresolved1-error1    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E, \u5E76\u4E14\u6B64\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'    unresolved2-error1    \n/set format verbose unrerr ' \u8FD9\u4E9B\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'                              unresolved0-error2    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E\u5E76\u4E14\u8FD9\u4E9B\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'  unresolved1-error2    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E\u5E76\u4E14\u8FD9\u4E9B\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}' unresolved2-error2    \n\n/set format verbose resolve '{until}{unrerr}'                                                   added,modified,replaced,used    \n\n/set format verbose typeKind '\u7C7B'                  class    \n/set format verbose typeKind '\u63A5\u53E3'              interface    \n/set format verbose typeKind '\u679A\u4E3E'                   enum    \n/set format verbose typeKind '\u6CE8\u91CA\u63A5\u53E3'   annotation    \n\n/set format verbose \
-result '{name} ==> {value}{post}'                                        added,modified,replaced-ok-primary    \n\n/set format verbose display '{result}{pre}\u5DF2\u521B\u5EFA\u6682\u5B58\u53D8\u91CF {name} : {type}{post}'    expression-added,modified,replaced-primary    \n/set format verbose display '{result}{pre}{name} \u7684\u503C: {type}{post}'                    varvalue-primary    \n/set format verbose display '{result}{pre}\u5DF2\u5206\u914D\u7ED9 {name} : {type}{post}'                 assignment-primary    \n/set format verbose display '{result}{pre}{action} \u53D8\u91CF {name} : {type}{resolve}{post}'  varinit,vardecl    \n/set format verbose display '{pre}{action} \u53D8\u91CF {name}{resolve}{post}'                   vardecl,varinit-notdefined    \n/set format verbose display '{pre}{action} \u53D8\u91CF {name}{post}'                            dropped-vardecl,varinit,expression    \n/set format verbose display '{pre}{action} \u53D8\u91CF {name}, \u91CD\u7F6E\u4E3A\u7A7A\u503C{post}'             replaced-vardecl,varinit-ok-update    \n\n/set format verbose display '{pre}{action} {typeKind} {name}{resolve}{post}'                 class,interface,enum,annotation    \n/set format verbose display '{pre}{action} \u65B9\u6CD5 {name}({type}){resolve}{post}'             method    \n\n/set format verbose display '{pre}\u5DF2\u5C1D\u8BD5\u4F7F\u7528 {typeKind} {name}{resolve}{post}'         used-class,interface,enum,annotation    \n/set format verbose display '{pre}\u5DF2\u5C1D\u8BD5\u8C03\u7528\u65B9\u6CD5 {name}({type}){resolve}{post}'    used-method    \n\n/set truncation verbose 80\n/set truncation verbose 1000                                                                  varvalue,expression\n\n/set mode normal -command verbose    \n/set format normal display ''                                                               added,modified,replaced,overwrote,dropped-update    \n/set format normal display '{pre}{action} \u53D8\u91CF {name}, \u91CD\u7F6E\u4E3A\u7A7A\u503C{post}'             replaced-vardecl,varinit-ok-update    \n/set format normal display '{result}'                                                       added,modified,replaced-expression,varvalue,assignment,varinit,vardecl-ok-primary    \n/set mode concise -quiet normal    \n\n/set prompt concise 'jshell> '   '   ...> '    \n\n/set format concise display ''                                                              class,interface,enum,annotation,method,assignment,varinit,vardecl-ok    \n\n/set feedback normal    \n\n/set mode silent -quiet    \n/set prompt silent '-> ' '>> '    \n/set format silent pre '|  '    \n/set format silent post '%n'    \n/set format silent errorpre '|  '    \n/set format silent errorpost '%n'    \n/set format silent display ''    \n
+startup.feedback = /set mode verbose -command    \n\n/set prompt verbose '\\njshell> '   '   ...> '    \n\n/set format verbose pre '|  '    \n/set format verbose post '%n'    \n/set format verbose errorpre '|  '    \n/set format verbose errorpost '%n'    \n\n/set format verbose errorline '{post}{pre}    {err}'    \n\n/set format verbose action '\u5DF2\u521B\u5EFA' added-primary    \n/set format verbose action '\u5DF2\u4FEE\u6539' modified-primary    \n/set format verbose action '\u5DF2\u66FF\u6362' replaced-primary    \n/set format verbose action '\u5DF2\u8986\u76D6' overwrote-primary    \n/set format verbose action '\u5DF2\u5220\u9664' dropped-primary    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u521B\u5EFA' added-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u4FEE\u6539' modified-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u66FF\u6362' replaced-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u8986\u76D6' overwrote-update    \n/set format verbose action '  \u66F4\u65B0\u5DF2\u5220\u9664' dropped-update    \n\n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u5B9E\u4F8B\u5316\u6216\u8005\u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'   defined-class-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                      defined-interface-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u4F7F\u7528, \u76F4\u81F3'                                  defined-enum,annotation-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                               defined-method-primary    \n/set format verbose until ', \u4E0D\u8FC7, \u5B83\u65E0\u6CD5\u5F15\u7528, \u76F4\u81F3'                            notdefined-primary    \n/set format verbose until ' \u5B83\u65E0\u6CD5\u5B9E\u4F8B\u5316\u6216\u8005\u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'          defined-class-update    \n/set format verbose until ' \u5176\u65B9\u6CD5\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                              defined-interface-update    \n/set format verbose until ' \u5B83\u65E0\u6CD5\u8C03\u7528, \u76F4\u81F3'                                      defined-method-update    \n/set format verbose until ' \u5B83\u65E0\u6CD5\u5F15\u7528, \u76F4\u81F3'                                   notdefined-update    \n\n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E'                                           unresolved1-error0    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E'                                          unresolved2-error0    \n/set format verbose unrerr ' \u6B64\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'                                 unresolved0-error1    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E, \u5E76\u4E14\u6B64\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'     unresolved1-error1    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E, \u5E76\u4E14\u6B64\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'    unresolved2-error1    \n/set format verbose unrerr ' \u8FD9\u4E9B\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'                              unresolved0-error2    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E\u5E76\u4E14\u8FD9\u4E9B\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}'  unresolved1-error2    \n/set format verbose unrerr '{unresolved} \u5DF2\u58F0\u660E\u5E76\u4E14\u8FD9\u4E9B\u9519\u8BEF\u5DF2\u66F4\u6B63: {errors}' unresolved2-error2    \n\n/set format verbose resolve '{until}{unrerr}'                                                   defined,notdefined-added,modified,replaced,used    \n\n/set format verbose typeKind '\u7C7B'                  class    \n/set format verbose typeKind '\u63A5\u53E3'              interface    \n/set format verbose typeKind '\u679A\u4E3E'                   enum    \n/set format verbose typeKind '\u6CE8\u91CA\u63A5\u53E3'   annotation    \
+\n\n/set format verbose result '{name} ==> {value}{post}'                                        added,modified,replaced-ok-primary    \n\n/set format verbose display '{result}{pre}\u5DF2\u521B\u5EFA\u6682\u5B58\u53D8\u91CF {name} : {type}{post}'    expression-added,modified,replaced-primary    \n/set format verbose display '{result}{pre}{name} \u7684\u503C: {type}{post}'                    varvalue-added,modified,replaced-primary    \n/set format verbose display '{result}{pre}\u5DF2\u5206\u914D\u7ED9 {name} : {type}{post}'                 assignment-primary    \n/set format verbose display '{result}{pre}{action} \u53D8\u91CF {name} : {type}{resolve}{post}'  varinit,vardecl    \n/set format verbose display '{pre}{action} \u53D8\u91CF {name}{resolve}{post}'                   vardecl,varinit-notdefined    \n/set format verbose display '{pre}{action} \u53D8\u91CF {name}{post}'                            dropped-vardecl,varinit,expression    \n/set format verbose display '{pre}{action} \u53D8\u91CF {name}, \u91CD\u7F6E\u4E3A\u7A7A\u503C{post}'             replaced-vardecl,varinit-ok-update    \n\n/set format verbose display '{pre}{action} {typeKind} {name}{resolve}{post}'                 class,interface,enum,annotation    \n/set format verbose display '{pre}{action} \u65B9\u6CD5 {name}({type}){resolve}{post}'             method    \n\n/set format verbose display '{pre}\u5DF2\u5C1D\u8BD5\u4F7F\u7528 {typeKind} {name}{resolve}{post}'         used-class,interface,enum,annotation    \n/set format verbose display '{pre}\u5DF2\u5C1D\u8BD5\u8C03\u7528\u65B9\u6CD5 {name}({type}){resolve}{post}'    used-method    \n\n/set truncation verbose 80\n/set truncation verbose 1000                                                                  varvalue,expression\n\n/set mode normal -command verbose    \n/set format normal display ''                                                               added,modified,replaced,overwrote,dropped-update    \n/set format normal display '{pre}{action} \u53D8\u91CF {name}, \u91CD\u7F6E\u4E3A\u7A7A\u503C{post}'             replaced-vardecl,varinit-ok-update    \n/set format normal display '{result}'                                                       added,modified,replaced-expression,varvalue,assignment,varinit,vardecl-ok-primary    \n/set mode concise -quiet normal    \n\n/set prompt concise 'jshell> '   '   ...> '    \n\n/set format concise display ''                                                              class,interface,enum,annotation,method,assignment,varinit,vardecl-ok    \n\n/set feedback normal    \n\n/set mode silent -quiet    \n/set prompt silent '-> ' '>> '    \n/set truncation silent 80\n/set truncation silent 1000                                                                  varvalue,expression\n/set format silent pre '|  '    \n/set format silent post '%n'    \n/set format silent errorpre '|  '    \n/set format silent errorpost '%n'    \n/set format silent display ''    \n
--- a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java	Tue Dec 13 02:04:23 2016 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363 8168766
+ * @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363 8168766 8168688
  * @summary Test modules support in javadoc.
  * @author bpatel
  * @library ../lib
@@ -56,6 +56,7 @@
         checkModuleClickThrough(true);
         checkModuleFilesAndLinks(true);
         checkModulesInSearch(true);
+        checkOverviewFrame(true);
     }
 
     /**
@@ -76,6 +77,7 @@
         checkModuleClickThrough(true);
         checkModuleFilesAndLinks(true);
         checkModulesInSearch(true);
+        checkOverviewFrame(true);
     }
 
     /**
@@ -92,6 +94,7 @@
         checkNoDescription(true);
         checkModuleLink();
         checkModuleFilesAndLinks(true);
+        checkOverviewFrame(true);
     }
 
     /**
@@ -108,6 +111,7 @@
         checkHtml5NoDescription(true);
         checkModuleLink();
         checkModuleFilesAndLinks(true);
+        checkOverviewFrame(true);
     }
 
     /**
@@ -123,6 +127,7 @@
         checkModuleClickThrough(false);
         checkModuleFilesAndLinks(false);
         checkModulesInSearch(false);
+        checkOverviewFrame(false);
     }
 
     /**
@@ -137,6 +142,7 @@
         checkHtml5OverviewSummaryPackages();
         checkModuleFilesAndLinks(false);
         checkModulesInSearch(false);
+        checkOverviewFrame(false);
     }
 
     /**
@@ -179,6 +185,7 @@
                 "testpkgmdl1");
         checkExit(Exit.OK);
         checkModuleFilesAndLinks(true);
+        checkNegatedOverviewFrame();
     }
 
     /**
@@ -620,4 +627,18 @@
         checkOutput("module2-summary.html", false,
                 "@AnnotationTypeUndocumented");
 }
+
+    void checkOverviewFrame(boolean found) {
+        checkOutput("index.html", !found,
+                "<iframe src=\"overview-frame.html\" name=\"packageListFrame\" title=\"All Packages\"></iframe>");
+        checkOutput("index.html", found,
+                "<iframe src=\"module-overview-frame.html\" name=\"packageListFrame\" title=\"All Modules\"></iframe>");
 }
+
+    void checkNegatedOverviewFrame() {
+        checkOutput("index.html", false,
+                "<iframe src=\"overview-frame.html\" name=\"packageListFrame\" title=\"All Packages\"></iframe>");
+        checkOutput("index.html", false,
+                "<iframe src=\"module-overview-frame.html\" name=\"packageListFrame\" title=\"All Modules\"></iframe>");
+    }
+}
--- a/langtools/test/jdk/javadoc/tool/CheckResourceKeys.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/test/jdk/javadoc/tool/CheckResourceKeys.java	Tue Dec 13 02:04:23 2016 +0100
@@ -26,6 +26,9 @@
  * @bug 8000612
  * @summary need test program to validate javadoc resource bundles
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ *          jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.resources:open
+ *          jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.resources:open
+ *          jdk.javadoc/jdk.javadoc.internal.tool.resources:open
  *          jdk.jdeps/com.sun.tools.classfile
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/api/TestName.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8170251
+ * @summary     Add javax.tools.Tool.name()
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ */
+
+import java.util.Optional;
+import java.util.ServiceLoader;
+import javax.tools.Tool;
+import jdk.javadoc.internal.api.JavadocTool;
+
+public class TestName {
+    public static void main(String... args) throws Exception {
+        new TestName().run();
+    }
+
+    public void run() throws Exception {
+        Optional<Tool> opt = findFirst("javadoc");
+        if (!opt.isPresent()) {
+            throw new Exception("tool not found");
+        }
+        if (!(opt.get() instanceof JavadocTool)) {
+            throw new Exception("unexpected tool found");
+        }
+    }
+
+    Optional<Tool> findFirst(String name) {
+        getClass().getModule().addUses(Tool.class);
+        for (Tool p : ServiceLoader.load(Tool.class,
+                ClassLoader.getSystemClassLoader())) {
+            if (p.name().equals(name)) {
+                return Optional.of(p);
+            }
+        }
+        return Optional.empty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8170667/ParameterProcessor.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static java.util.stream.Collectors.toCollection;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
+
+/*
+ * @test
+ * @bug 8170667
+ * @summary ClassReader assigns method parameters from MethodParameters incorrectly when long/double
+ * parameters are present
+ * @library /tools/javac/lib
+ * @modules java.compiler
+ *          jdk.compiler
+ * @compile -parameters ParameterProcessor.java
+ * @compile/process -proc:only -processor ParameterProcessor ParameterProcessor
+ */
+@SupportedAnnotationTypes("ParameterProcessor.ParameterNames")
+public class ParameterProcessor extends JavacTestingAbstractProcessor {
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    @interface ParameterNames {
+        String[] value() default {};
+    }
+
+    @ParameterProcessor.ParameterNames({"a", "b", "c"})
+    void f(int a, int b, int c) {}
+
+    @ParameterProcessor.ParameterNames({"d", "e", "f"})
+    void g(int d, long e, int f) {}
+
+    @ParameterProcessor.ParameterNames({"g", "h", "i", "j"})
+    void h(int g, double h, int i, int j) {}
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        for (Element element : roundEnv.getElementsAnnotatedWith(ParameterNames.class)) {
+            ParameterNames names = element.getAnnotation(ParameterNames.class);
+            if (names == null) {
+                continue;
+            }
+            List<String> expected = Arrays.asList(names.value());
+            List<String> actual =
+                    ((ExecutableElement) element)
+                            .getParameters()
+                            .stream()
+                            .map(p -> p.getSimpleName().toString())
+                            .collect(toCollection(ArrayList::new));
+            if (!expected.equals(actual)) {
+                String message =
+                        String.format(
+                                "bad parameter names for %s#%s; expected: %s, was: %s",
+                                element, element, expected, actual);
+                messager.printMessage(Kind.ERROR, message);
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/api/TestName.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8170251
+ * @summary     Add javax.tools.Tool.name()
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ */
+
+import java.util.Optional;
+import java.util.ServiceLoader;
+import javax.tools.Tool;
+import com.sun.tools.javac.api.JavacTool;
+
+public class TestName {
+    public static void main(String... args) throws Exception {
+        new TestName().run();
+    }
+
+    public void run() throws Exception {
+        Optional<Tool> opt = findFirst("javac");
+        if (!opt.isPresent()) {
+            throw new Exception("tool not found");
+        }
+        if (!(opt.get() instanceof JavacTool)) {
+            throw new Exception("unexpected tool found");
+        }
+    }
+
+    Optional<Tool> findFirst(String name) {
+        getClass().getModule().addUses(Tool.class);
+        for (Tool p : ServiceLoader.load(Tool.class,
+                ClassLoader.getSystemClassLoader())) {
+            if (p.name().equals(name)) {
+                return Optional.of(p);
+            }
+        }
+        return Optional.empty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/boxing/QualBoxedPostOp.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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 8147527
+ * @summary Qualified "this" and "super" boxed unary post operations.
+ * @compile QualBoxedPostOp.java
+ * @run main QualBoxedPostOp
+ */
+public class QualBoxedPostOp extends Parent {
+    public static void main(String[] args) {
+        new QualBoxedPostOp().testAll();
+    }
+
+    private void testAll() {
+        equals(test(), 0);
+        equals(i, 1);
+
+        Inner in = new Inner();
+        equals(in.test(), 1);
+        equals(i, 2);
+
+        equals(testParent(), 10);
+        equals(super.i, 11);
+
+        equals(in.testParent(), 11);
+        equals(super.i, 12);
+    }
+
+    private void equals(int a, int b) {
+        if (a != b) throw new Error();
+    }
+
+    Integer i=0;
+
+    private Integer test() {
+        return this.i++;
+    }
+    private Integer testParent() {
+        return super.i++;
+    }
+
+    class Inner {
+        private Integer test() {
+            return QualBoxedPostOp.this.i++;
+        }
+        private Integer testParent() {
+            return QualBoxedPostOp.super.i++;
+        }
+    }
+}
+
+class Parent {
+    protected Integer i=10;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/boxing/QualBoxedPostOp2.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8147527
+ * @summary Qualified "super" boxed unary post-operation using a type variable.
+ * @compile QualBoxedPostOp2.java
+ * @run main QualBoxedPostOp2
+ */
+public class QualBoxedPostOp2<T> extends Parent2<Integer> {
+    public static void main(String[] args) {
+        new QualBoxedPostOp2().testAll();
+    }
+
+    private void testAll() {
+        super.i = 10;
+
+        equals(new Inner().testParent(), 10);
+        equals(super.i, 11);
+    }
+
+    private void equals(int a, int b) {
+        if (a != b) throw new Error();
+    }
+
+    T i;
+
+    class Inner {
+        private Integer testParent() {
+            return QualBoxedPostOp2.super.i++;
+        }
+    }
+}
+
+class Parent2<T> {
+    protected T i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/boxing/QualBoxedPostOp3.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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 8147527
+ * @summary Verifies the runtime behavior of "super", "this" and "this$n" optimization for boxed unary post-operations.
+ * @compile QualBoxedPostOp3.java QualBoxedPostOp3Parent.java
+ * @run main QualBoxedPostOp3
+ */
+public class QualBoxedPostOp3 extends p.QualBoxedPostOp3Parent {
+    public static void main(String[] args) {
+        new QualBoxedPostOp3().testAll();
+    }
+
+    private void testAll() {
+        equals(test(), 1);
+        equals(i, 2);
+
+        Inner in = new Inner();
+        equals(in.test(), 3);
+        equals(i, 4);
+
+        equals(testParent(), 21);
+        equals(super.j, 22);
+
+        equals(in.testParent(), 23);
+        equals(super.j, 24);
+    }
+
+    private void equals(int a, int b) {
+        if (a != b) throw new Error();
+    }
+
+    Integer i=0;
+
+    private Integer test() {
+        i++;
+        return this.i++;
+    }
+    private Integer testParent() {
+        j++;
+        return super.j++;
+    }
+
+    class Inner {
+        private Integer test() {
+            i++;
+            return QualBoxedPostOp3.this.i++;
+        }
+        private Integer testParent() {
+            j++;
+            return QualBoxedPostOp3.super.j++;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/boxing/QualBoxedPostOp3Parent.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package p;
+
+public class QualBoxedPostOp3Parent {
+    protected Integer j=20;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/desugar/BoxingAndSuper.java	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,395 @@
+/*
+ * 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
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.code
+ *          jdk.compiler/com.sun.tools.javac.comp
+ *          jdk.compiler/com.sun.tools.javac.tree
+ *          jdk.compiler/com.sun.tools.javac.util
+ */
+
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Lower;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
+import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.JCTree.LetExpr;
+import com.sun.tools.javac.tree.JCTree.Tag;
+import com.sun.tools.javac.tree.TreeCopier;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.WriterKind;
+import com.sun.tools.javac.util.Names;
+
+import toolbox.ToolBox;
+
+public class BoxingAndSuper {
+    public static void main(String... args) throws Exception {
+        new BoxingAndSuper().testSuper();
+        new BoxingAndSuper().testThis();
+    }
+
+    public void testSuper() throws Exception {
+        //super, same package:
+        runTest("package p;\n" +
+                "class Test extends Parent {\n" +
+                "     protected Integer i=20;\n" +
+                "     private Integer dump() {\n" +
+                "         return super.i++;\n" +
+                "     }\n" +
+                "}\n" +
+                "---" +
+                "package p;\n" +
+                "class Parent {\n" +
+                "     protected Integer i=10;\n" +
+                "} ",
+                "p.Test.dump()java.lang.Integer\n" +
+                "{\n" +
+                "    return (let /*synthetic*/ final Integer $le0 = (Integer)super.i " +
+                            "in (let /*synthetic*/ final Integer $le1 = super.i = Integer.valueOf((int)(super.i.intValue() + 1)) " +
+                                "in $le0));\n" +
+                "}\n");
+        //qualified super, same package:
+        runTest("package p;\n" +
+                "class Test extends Parent {\n" +
+                "     protected Integer i=20;\n" +
+                "     class Inner {\n" +
+                "         private Integer dump() {\n" +
+                "             return Test.super.i++;\n" +
+                "         }\n" +
+                "     }\n" +
+                "}\n" +
+                "---" +
+                "package p;\n" +
+                "class Parent {\n" +
+                "     protected Integer i=10;\n" +
+                "} ",
+                "p.Test.Inner.dump()java.lang.Integer\n" +
+                "{\n" +
+                "    return (let /*synthetic*/ final Integer $le0 = (Integer)Test.access$001(this$0) " +
+                            "in (let /*synthetic*/ final Integer $le1 = Test.access$103(this$0, Integer.valueOf((int)(Test.access$201(this$0).intValue() + 1))) " +
+                                "in $le0));\n" +
+                "}\n" +
+                "p.Test.access$001(p.Test)java.lang.Integer\n" +
+                "{\n" +
+                "    return x0.i;\n" +
+                "}\n" +
+                "p.Test.access$103(p.Test,java.lang.Integer)java.lang.Integer\n" +
+                "{\n" +
+                "    return x0.i = x1;\n" +
+                "}\n" +
+                "p.Test.access$201(p.Test)java.lang.Integer\n" +
+                "{\n" +
+                "    return x0.i;\n" +
+                "}\n");
+        //super, different packages:
+        runTest("package p1;\n" +
+                "class Test extends p2.Parent {\n" +
+                "     protected Integer i=20;\n" +
+                "     private Integer dump() {\n" +
+                "         return super.i++;\n" +
+                "     }\n" +
+                "}\n" +
+                "---" +
+                "package p2;\n" +
+                "public class Parent {\n" +
+                "     protected Integer i=10;\n" +
+                "} ",
+                "p1.Test.dump()java.lang.Integer\n" +
+                "{\n" +
+                "    return (let /*synthetic*/ final Integer $le0 = (Integer)super.i " +
+                            "in (let /*synthetic*/ final Integer $le1 = super.i = Integer.valueOf((int)(super.i.intValue() + 1)) " +
+                                "in $le0));\n" +
+                "}\n");
+        //qualified super, different packages:
+        runTest("package p1;\n" +
+                "class Test extends p2.Parent {\n" +
+                "     protected Integer i=20;\n" +
+                "     class Inner {\n" +
+                "         private Integer dump() {\n" +
+                "             return Test.super.i++;\n" +
+                "         }\n" +
+                "     }\n" +
+                "}\n" +
+                "---" +
+                "package p2;\n" +
+                "public class Parent {\n" +
+                "     protected Integer i=10;\n" +
+                "} ",
+                "p1.Test.Inner.dump()java.lang.Integer\n" +
+                "{\n" +
+                "    return (let /*synthetic*/ final Integer $le0 = (Integer)Test.access$001(this$0) " +
+                            "in (let /*synthetic*/ final Integer $le1 = Test.access$103(this$0, Integer.valueOf((int)(Test.access$201(this$0).intValue() + 1))) " +
+                                "in $le0));\n" +
+                "}\n" +
+                "p1.Test.access$001(p1.Test)java.lang.Integer\n" +
+                "{\n" +
+                "    return x0.i;\n" +
+                "}\n" +
+                "p1.Test.access$103(p1.Test,java.lang.Integer)java.lang.Integer\n" +
+                "{\n" +
+                "    return x0.i = x1;\n" +
+                "}\n" +
+                "p1.Test.access$201(p1.Test)java.lang.Integer\n" +
+                "{\n" +
+                "    return x0.i;\n" +
+                "}\n");
+    }
+
+    public void testThis() throws Exception {
+        String code = "public class Test {\n" +
+                      "    Integer i;\n" +
+                      "    private void dump() {\n" +
+                      "        i++;\n" +
+                      "        this.i++;\n" +
+                      "    }\n" +
+                      "}";
+        String expected =
+                "Test.dump()void\n" +
+                "{\n" +
+                "    (let /*synthetic*/ final Integer $le0 = i in (let /*synthetic*/ final Integer $le1 = i = Integer.valueOf((int)(i.intValue() + 1)) in $le0));\n" +
+                "    (let /*synthetic*/ final Integer $le2 = (Integer)this.i in (let /*synthetic*/ final Integer $le3 = this.i = Integer.valueOf((int)(this.i.intValue() + 1)) in $le2));\n" +
+                "}\n";
+        runTest(code, expected);
+        //qualified this:
+        runTest("public class Test {\n" +
+                "   Integer i;\n" +
+                "   class Inner1 {\n" +
+                "       class Inner2 {\n" +
+                "           private Integer dump() {\n" +
+                "               return Test.this.i++;\n" +
+                "           }\n" +
+                "       }\n" +
+                "   }\n" +
+                "}",
+                "Test.Inner1.Inner2.dump()java.lang.Integer\n" +
+                "{\n" +
+                "    return (let /*synthetic*/ final Integer $le0 = (Integer)this$1.this$0.i" +
+                           " in (let /*synthetic*/ final Integer $le1 = this$1.this$0.i = " +
+                                "Integer.valueOf((int)(this$1.this$0.i.intValue() + 1)) " +
+                                "in $le0));\n" +
+                "}\n"
+        );
+    }
+
+    private final ToolBox tb = new ToolBox();
+
+    private void runTest(String code, String expectedDesugar) throws Exception {
+        List<JavaFileObject> files = List.nil();
+
+        for (String file : code.split("---")) {
+            files = files.prepend(new ToolBox.JavaSource(file));
+        }
+
+        Path classes = Paths.get("classes");
+
+        if (Files.exists(classes)) {
+            tb.cleanDirectory(classes);
+        } else {
+            Files.createDirectories(classes);
+        }
+
+        JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler();
+        StringWriter out = new StringWriter();
+        Context context = new Context();
+        TestLower.preRegister(context);
+        Iterable<String> options = Arrays.asList("-d", classes.toString());
+        JavacTask task = (JavacTask) compiler.getTask(out, null, null, options, null, files, context);
+
+        task.generate();
+
+        out.flush();
+
+        String actual = out.toString().replace(System.getProperty("line.separator"), "\n");
+
+        if (!expectedDesugar.equals(actual)) {
+            throw new IllegalStateException("Actual does not match expected: " + actual);
+        }
+    }
+
+    private static final class TestLower extends Lower {
+
+        public static void preRegister(Context context) {
+            context.put(lowerKey, new Context.Factory<Lower>() {
+                   public Lower make(Context c) {
+                       return new TestLower(c);
+                   }
+            });
+        }
+
+        private final TreeMaker make;
+        private final Names names;
+        private final Log log;
+
+        public TestLower(Context context) {
+            super(context);
+            make = TreeMaker.instance(context);
+            names = Names.instance(context);
+            log = Log.instance(context);
+        }
+
+        @Override
+        public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
+            List<JCTree> result = super.translateTopLevelClass(env, cdef, make);
+            Map<Symbol, JCMethodDecl> declarations = new HashMap<>();
+            Set<Symbol> toDump = new TreeSet<>(symbolComparator);
+
+            new TreeScanner() {
+                @Override
+                public void visitMethodDef(JCMethodDecl tree) {
+                    if (tree.name.toString().startsWith("dump")) {
+                        toDump.add(tree.sym);
+                    }
+                    declarations.put(tree.sym, tree);
+                    super.visitMethodDef(tree);
+                }
+            }.scan(result);
+
+            for (Symbol d : toDump) {
+                dump(d, declarations, new HashSet<>());
+            }
+
+            return result;
+        }
+
+        private void dump(Symbol methodSym, Map<Symbol, JCMethodDecl> declarations, Set<Symbol> alreadyPrinted) {
+            if (!alreadyPrinted.add(methodSym))
+                return ;
+
+            JCMethodDecl method = declarations.get(methodSym);
+
+            if (method == null) {
+                return ;
+            }
+
+            log.getWriter(WriterKind.NOTICE).println(symbol2String(methodSym));
+
+            JCBlock body = new TreeCopier<Void>(make) {
+                private final Map<String, String> letExprRemap = new HashMap<>();
+                private int i;
+
+                @Override
+                public JCTree visitOther(Tree node, Void p) {
+                    JCTree tree = (JCTree) node;
+                    if (tree.hasTag(Tag.LETEXPR)) {
+                        LetExpr le = (LetExpr) tree;
+
+                        for (JCVariableDecl var : le.defs) {
+                            letExprRemap.put(var.name.toString(), "$le" + i++);
+                        }
+                    }
+                    return super.visitOther(node, p);
+                }
+
+                @Override
+                public JCTree visitVariable(VariableTree node, Void p) {
+                    String newName = letExprRemap.get(node.getName().toString());
+                    if (newName != null) {
+                        node = make.VarDef((JCModifiers) node.getModifiers(), names.fromString(newName), (JCExpression) node.getType(), (JCExpression) node.getInitializer());
+                    }
+                    return super.visitVariable(node, p);
+                }
+
+                @Override
+                public JCTree visitIdentifier(IdentifierTree node, Void p) {
+                    String newName = letExprRemap.get(node.getName().toString());
+                    if (newName != null) {
+                        node = make.Ident(names.fromString(newName));
+                    }
+                    return super.visitIdentifier(node, p);
+                }
+
+                @Override
+                public <T extends JCTree> T copy(T tree, Void p) {
+                    if (tree.hasTag(Tag.LETEXPR)) {
+                        return (T) visitOther(tree, p);
+                    }
+                    return super.copy(tree, p);
+                }
+
+            }.copy(method.body);
+            log.getWriter(WriterKind.NOTICE).println(body.toString());
+
+            Set<Symbol> invoked = new TreeSet<>(symbolComparator);
+
+            new TreeScanner() {
+                @Override
+                public void visitApply(JCMethodInvocation tree) {
+                    invoked.add(TreeInfo.symbol(tree.meth));
+                    super.visitApply(tree);
+                }
+            }.scan(method);
+
+            for (Symbol search : invoked) {
+                dump(search, declarations, alreadyPrinted);
+            }
+        }
+
+        private String symbol2String(Symbol sym) {
+            switch (sym.kind) {
+                case TYP:
+                    return sym.getQualifiedName().toString();
+                case MTH:
+                    return symbol2String(sym.owner) + "." + sym.name + sym.type.toString();
+                default:
+                    throw new UnsupportedOperationException();
+            }
+        }
+
+        private final Comparator<Symbol> symbolComparator = (s1, s2) -> symbol2String(s1).compareTo(symbol2String(s2));
+    }
+
+}
--- a/langtools/test/tools/javac/diags/CheckExamples.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/test/tools/javac/diags/CheckExamples.java	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
  *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.javac.resources:open
  *          jdk.compiler/com.sun.tools.javac.util
  * @build Example CheckExamples DocCommentProcessor
  * @run main/othervm CheckExamples
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java	Tue Dec 13 02:04:23 2016 +0100
@@ -25,8 +25,9 @@
  * @test
  * @bug 6964768 6964461 6964469 6964487 6964460 6964481 6980021
  * @summary need test program to validate javac resource bundles
- * @modules jdk.jdeps/com.sun.tools.classfile
- *          jdk.compiler/com.sun.tools.javac.code
+ * @modules jdk.compiler/com.sun.tools.javac.code
+ *          jdk.compiler/com.sun.tools.javac.resources:open
+ *          jdk.jdeps/com.sun.tools.classfile
  */
 
 import java.io.*;
--- a/langtools/test/tools/javac/warnings/VerifyLintDescriptions.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/test/tools/javac/warnings/VerifyLintDescriptions.java	Tue Dec 13 02:04:23 2016 +0100
@@ -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
@@ -26,6 +26,7 @@
  * @bug 8033961
  * @summary Verify that all LintCategories have their descriptions filled.
  * @modules jdk.compiler/com.sun.tools.javac.code
+ *          jdk.compiler/com.sun.tools.javac.resources:open
  *          jdk.compiler/com.sun.tools.javac.util
  */
 
--- a/langtools/test/tools/javadoc/CheckResourceKeys.java	Fri Dec 16 01:46:00 2016 -0800
+++ b/langtools/test/tools/javadoc/CheckResourceKeys.java	Tue Dec 13 02:04:23 2016 +0100
@@ -25,7 +25,10 @@
  * @test
  * @bug 8000612
  * @summary need test program to validate javadoc resource bundles
- * @modules jdk.jdeps/com.sun.tools.classfile
+ * @modules jdk.javadoc/com.sun.tools.doclets.formats.html.resources:open
+ *          jdk.javadoc/com.sun.tools.doclets.internal.toolkit.resources:open
+ *          jdk.javadoc/com.sun.tools.javadoc.resources:open
+ *          jdk.jdeps/com.sun.tools.classfile
  */
 
 import java.io.*;
--- a/make/Javadoc.gmk	Fri Dec 16 01:46:00 2016 -0800
+++ b/make/Javadoc.gmk	Tue Dec 13 02:04:23 2016 +0100
@@ -499,6 +499,21 @@
 
 ################################################################################
 
+$(eval $(call SetupJavadocGeneration, httpclient, \
+    MODULES := jdk.incubator.httpclient, \
+    PACKAGES := \
+        jdk.incubator.http, \
+    API_ROOT := jre, \
+    DEST_DIR := incubator/httpclient/spec, \
+    TITLE := Java&trade; HTTP Client API (incubator module), \
+    FIRST_COPYRIGHT_YEAR := 2015, \
+    DISABLED_DOCLINT := accessibility missing syntax, \
+))
+
+TARGETS += $(httpclient)
+
+################################################################################
+
 $(eval $(call SetupJavadocGeneration, jsobject, \
     MODULES := jdk.jsobject, \
     PACKAGES := netscape.javascript, \
--- a/make/common/MakeBase.gmk	Fri Dec 16 01:46:00 2016 -0800
+++ b/make/common/MakeBase.gmk	Tue Dec 13 02:04:23 2016 +0100
@@ -507,14 +507,18 @@
 	if [ -n "`$(XATTR) -l '$@'`" ]; then $(XATTR) -c '$@'; fi
   endef
 else
-  # Running mkdir and cp in the same shell speeds up copy intensive tasks in Cygwin
-  # significantly.
   define install-file
 	$(call MakeDir, $(@D))
 	$(CP) -fP '$<' '$@'
   endef
 endif
 
+# Variant of install file that does not preserve symlinks
+define install-file-nolink
+	$(call MakeDir, $(@D))
+	$(CP) -f '$<' '$@'
+endef
+
 ################################################################################
 # Take two paths and return the path of the last common directory.
 # Ex: /foo/bar/baz, /foo/bar/banan -> /foo/bar
--- a/make/common/Modules.gmk	Fri Dec 16 01:46:00 2016 -0800
+++ b/make/common/Modules.gmk	Tue Dec 13 02:04:23 2016 +0100
@@ -48,7 +48,6 @@
     java.base \
     java.datatransfer \
     java.desktop \
-    java.httpclient \
     java.instrument \
     java.logging \
     java.management \
@@ -98,6 +97,7 @@
 
 PLATFORM_MODULES += \
     java.compiler \
+    jdk.incubator.httpclient \
     java.scripting \
     java.security.jgss \
     java.smartcardio \
--- a/make/devkit/Tools.gmk	Fri Dec 16 01:46:00 2016 -0800
+++ b/make/devkit/Tools.gmk	Tue Dec 13 02:04:23 2016 +0100
@@ -85,8 +85,8 @@
     libgcc \
     elfutils elfutils-libs elfutils-devel \
     elfutils-libelf elfutils-libelf-devel \
-    zlib zlib-devel
-
+    zlib zlib-devel \
+    libffi libffi-devel
 
 ifeq ($(ARCH),x86_64)
   RPM_DIR ?= $(RPM_DIR_x86_64)
@@ -209,6 +209,18 @@
 	@touch $@
 
 ##########################################################################################
+# Create links for ffi header files so that they become visible by default when using the
+# devkit.
+
+$(SYSROOT)/usr/include/ffi.h: $(rpms)
+	cd $(@D) && rm $(@F) && ln -s ../lib/libffi-*/include/$(@F) .
+
+$(SYSROOT)/usr/include/ffitarget.h: $(rpms)
+	cd $(@D) && rm $(@F) && ln -s ../lib/libffi-*/include/$(@F) .
+
+SYSROOT_LINKS += $(SYSROOT)/usr/include/ffi.h $(SYSROOT)/usr/include/ffitarget.h
+
+##########################################################################################
 
 # Define marker files for each source package to be compiled
 $(foreach t,binutils mpfr gmp mpc gcc ccache,$(eval $(t) = $(TARGETDIR)/$($(t)_ver).done))
@@ -496,7 +508,7 @@
 libs : $(libs)
 sysroot : rpms libs
 gcc : sysroot $(gcc) $(gccpatch)
-all : binutils gcc bfdlib $(PREFIX)/devkit.info $(missing-links)
+all : binutils gcc bfdlib $(PREFIX)/devkit.info $(missing-links) $(SYSROOT_LINKS)
 
 # this is only built for host. so separate.
 ccache : $(ccache)
--- a/make/jprt.properties	Fri Dec 16 01:46:00 2016 -0800
+++ b/make/jprt.properties	Tue Dec 13 02:04:23 2016 +0100
@@ -118,6 +118,12 @@
 jprt.windows_i586.fastdebugOpen.build.jib.profile=windows-x86-open-debug
 jprt.windows_x64.fastdebugOpen.build.jib.profile=windows-x64-open-debug
 
+jprt.linux_i586.productZero.build.jib.profile=linux-x86-zero
+jprt.linux_x64.productZero.build.jib.profile=linux-x64-zero
+
+jprt.linux_i586.fastdebugZero.build.jib.profile=linux-x86-zero-debug
+jprt.linux_x64.fastdebugZero.build.jib.profile=linux-x64-zero-debug
+
 jprt.test.jib.profile=run-test
 
 # Set make target to use for different build flavors
@@ -128,6 +134,8 @@
 jprt.build.flavor.optimized.target=jprt_bundle
 jprt.build.flavor.optimizedOpen.target=jprt_bundle
 jprt.build.flavor.slowdebug.target=jprt_bundle
+jprt.build.flavor.productZero.target=jprt_bundle
+jprt.build.flavor.fastdebugZero.target=jprt_bundle
 
 # Use these configure args to define debug level or provide specific
 # configuration details not covered by Jib profiles.
@@ -181,7 +189,7 @@
 jprt.build.configure.args=						\
     --with-output-sync=recurse						\
     --with-jobs=$ALT_PARALLEL_COMPILE_JOBS				\
-    --with-version-opt=$JPRT_JOB_ID				 	\
+    --with-version-opt=$JPRT_JOB_ID					\
     ${my.additional.build.configure.args.${jprt.test.set}}		\
     ${my.custom.build.configure.args}
 
@@ -481,15 +489,15 @@
 ################################################################################
 # Testset buildinfra
 my.build.flavors.buildinfra = \
-    product,fastdebug,slowdebug, \
+    product,fastdebug,slowdebug,productZero,fastdebugZero \
     ${my.additional.build.flavors.buildinfra}
 
 # Platforms built for hotspot push jobs
 my.build.targets.buildinfra = \
     solaris_sparcv9_5.11-{product|fastdebug|slowdebug}, \
     solaris_x64_5.11-{product|fastdebug|slowdebug}, \
-    linux_i586_3.8-{product|fastdebug|slowdebug}, \
-    linux_x64_3.8-{product|fastdebug|slowdebug}, \
+    linux_i586_3.8-{product|fastdebug|slowdebug|productZero|fastdebugZero}, \
+    linux_x64_3.8-{product|fastdebug|slowdebug|productZero|fastdebugZero}, \
     macosx_x64_10.9-{product|fastdebug|slowdebug}, \
     windows_i586_6.3-{product|fastdebug|slowdebug}, \
     windows_x64_6.3-{product|fastdebug|slowdebug}, \
--- a/nashorn/.hgtags	Fri Dec 16 01:46:00 2016 -0800
+++ b/nashorn/.hgtags	Tue Dec 13 02:04:23 2016 +0100
@@ -381,3 +381,4 @@
 4a68dd740be8aa0d1a25f94985b3cb2e190ccfce jdk-9+145
 55f5a96988de8237f3ee65a69aa4a48aed9ca8d4 jdk-9+146
 9e86d6383456a1eb0298c72bb9ca363939ad90cf jdk-9+147
+0a4bc2f049132ddc20985565bb41b2be8a458dda jdk-9+148
--- a/nashorn/test/Makefile	Fri Dec 16 01:46:00 2016 -0800
+++ b/nashorn/test/Makefile	Tue Dec 13 02:04:23 2016 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -23,256 +23,16 @@
 # questions.
 #
 
-#
-# Makefile to run various nashorn tests
-#
-
-.DEFAULT : all
-
-# Empty these to get rid of some default rules
-.SUFFIXES:
-.SUFFIXES: .java
-CO=
-GET=
-
-# Utilities used
-AWK       = awk
-CAT       = cat
-CD        = cd
-CHMOD     = chmod
-CP        = cp
-CUT       = cut
-DIRNAME   = dirname
-ECHO      = echo
-EGREP     = egrep
-EXPAND    = expand
-FIND      = find
-MKDIR     = mkdir
-PWD       = pwd
-SED       = sed
-SORT      = sort
-TEE       = tee
-UNAME     = uname
-UNIQ      = uniq
-WC        = wc
-ZIPEXE    = zip
-
-# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
-UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
-
-# Commands to run on paths to make mixed paths for java on windows
-ifeq ($(UNAME_S), CYGWIN)
-  # Location of developer shared files
-  SLASH_JAVA = J:
-  GETMIXEDPATH = cygpath -m
-else
-  # Location of developer shared files
-  SLASH_JAVA = /java
-
-  GETMIXEDPATH=$(ECHO)
-endif
-
-# Root of this test area (important to use full paths in some places)
-TEST_ROOT := $(shell $(PWD))
-
-# Root of all test results
-ifdef TEST_OUTPUT_DIR
-  $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg)
-  ABS_TEST_OUTPUT_DIR := \
-    $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD))
-else
-  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)
-endif
-
-# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
-ifndef PRODUCT_HOME
-  # Try to use images/jdk if it exists
-  ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/jdk
-  PRODUCT_HOME :=                       		\
-    $(shell                             		\
-      if [ -d $(ABS_JDK_IMAGE) ] ; then 		\
-         $(ECHO) "$(ABS_JDK_IMAGE)";    		\
-       else                             		\
-         $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)";		\
-       fi)
-  PRODUCT_HOME := $(PRODUCT_HOME)
-endif
-
-# Expect JPRT to set JPRT_PRODUCT_ARGS (e.g. -server etc.)
-#   Should be passed into 'java' only.
-#   Could include: -d64 -server -client OR any java option
-ifdef JPRT_PRODUCT_ARGS
-  JAVA_ARGS = $(JPRT_PRODUCT_ARGS)
-endif
+default: all
 
-# Expect JPRT to set JPRT_PRODUCT_VM_ARGS (e.g. -Xcomp etc.)
-#   Should be passed into anything running the vm (java, javac, javadoc, ...).
-ifdef JPRT_PRODUCT_VM_ARGS
-  JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS)
-endif
-
-# jtreg failure handler config
-ifeq ($(FAILURE_HANDLER_DIR), )
-  ifneq ($(TESTNATIVE_DIR), )
-    FAILURE_HANDLER_DIR := $(TESTNATIVE_DIR)/failure_handler
-  endif
-endif
-ifneq ($(FAILURE_HANDLER_DIR), )
-  FAILURE_HANDLER_DIR_MIXED := $(shell $(GETMIXEDPATH) "$(FAILURE_HANDLER_DIR)")
-  JTREG_FAILURE_HANDLER_OPTIONS := \
-      -timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-      -observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-      -timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \
-      -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver \
-      -timeoutHandlerTimeout:0
-  ifeq ($(UNAME_S), CYGWIN)
-    JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)"
-  endif
-endif
-
-# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
-ifdef JPRT_ARCHIVE_BUNDLE
-  ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
-else
-  ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
-endif
-
-# How to create the test bundle (pass or fail, we want to create this)
-#   Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
-ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`     \
-	           && $(CD) $(ABS_TEST_OUTPUT_DIR)             \
-	           && $(CHMOD) -R a+r . \
-	           && $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . )
-
-# important results files
-SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
-STATS_TXT_NAME = Stats.txt
-STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)")
-RUNLIST   = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt")
-PASSLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt")
-FAILLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt")
-EXITCODE  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt")
+USE_FAILURE_HANDLER := true
 
-TESTEXIT = \
-  if [ ! -s $(EXITCODE) ] ; then \
-    $(ECHO) "ERROR: EXITCODE file not filled in."; \
-    $(ECHO) "1" > $(EXITCODE); \
-  fi ; \
-  testExitCode=`$(CAT) $(EXITCODE)`; \
-  $(ECHO) "EXIT CODE: $${testExitCode}"; \
-  exit $${testExitCode}
-
-BUNDLE_UP_AND_EXIT = \
-( \
-  jtregExitCode=$$? && \
-  _summary="$(SUMMARY_TXT)"; \
-  $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
-  $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
-  if [ -r "$${_summary}" ] ; then \
-    $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
-    $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
-    $(EGREP) ' Passed\.' $(RUNLIST) \
-      | $(EGREP) -v ' Error\.' \
-      | $(EGREP) -v ' Failed\.' > $(PASSLIST); \
-    ( $(EGREP) ' Failed\.' $(RUNLIST); \
-      $(EGREP) ' Error\.' $(RUNLIST); \
-      $(EGREP) -v ' Passed\.' $(RUNLIST) ) \
-      | $(SORT) | $(UNIQ) > $(FAILLIST); \
-    if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \
-      $(EXPAND) $(FAILLIST) \
-        | $(CUT) -d' ' -f1 \
-        | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \
-      if [ $${jtregExitCode} = 0 ] ; then \
-        jtregExitCode=1; \
-      fi; \
-    fi; \
-    runc="`$(CAT) $(RUNLIST)      | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    passc="`$(CAT) $(PASSLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    failc="`$(CAT) $(FAILLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
-    exclc="FIXME CODETOOLS-7900176"; \
-    $(ECHO) "TEST STATS: name=$(UNIQUE_DIR)  run=$${runc}  pass=$${passc}  fail=$${failc}" \
-      >> $(STATS_TXT); \
-  else \
-    $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
-  fi; \
-  if [ -f $(STATS_TXT) ] ; then \
-    $(CAT) $(STATS_TXT); \
-  fi; \
-  $(ZIP_UP_RESULTS) ; \
-  $(TESTEXIT) \
-)
-
-################################################################
+include ../../test/TestCommon.gmk
 
 # Default make rule (runs default nashorn tests)
 all: nashorn_default
 	@$(ECHO) "Testing completed successfully"
 
-# Prep for output
-# Change execute permissions on shared library files.
-# Files in repositories should never have execute permissions, but
-# there are some tests that have pre-built shared libraries, and these
-# windows dll files must have execute permission. Adding execute
-# permission may happen automatically on windows when using certain
-# versions of mercurial but it cannot be guaranteed. And blindly
-# adding execute permission might be seen as a mercurial 'change', so
-# we avoid adding execute permission to repository files. But testing
-# from a plain source tree needs the chmod a+rx. Applying the chmod to
-# all shared libraries not just dll files. And with CYGWIN and sshd
-# service, you may need CYGWIN=ntsec for this to work.
-prep:
-	@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
-	@$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`
-	@if [ ! -d $(TEST_ROOT)/../.hg ] ; then                          \
-	  $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \)  \
-	        -exec $(CHMOD) a+rx {} \; ;                             \
-        fi
-
-# Cleanup
-clean:
-	@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
-	@$(RM) $(ARCHIVE_BUNDLE)
-
-################################################################
-
-# jtreg tests
-
-# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
-ifndef JT_HOME
-  JT_HOME = $(SLASH_JAVA)/re/jtreg/4.2/promoted/latest/binaries/jtreg
-  ifdef JPRT_JTREG_HOME
-    JT_HOME = $(JPRT_JTREG_HOME)
-  endif
-endif
-
-# Problematic tests to be excluded
-PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt))
-
-# Create exclude list for this platform and arch
-ifdef NO_EXCLUDES
-  JTREG_EXCLUSIONS =
-else
-  JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%)
-endif
-
-# convert list of directories to dos paths
-define MixedDirs
-$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}"))
-endef
-
-define SummaryInfo
-$(ECHO) "########################################################"
-$(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME))
-$(ECHO) "########################################################"
-endef
-
 # ------------------------------------------------------------------
 
 nashorn_%:
@@ -281,80 +41,3 @@
 	        $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \
 	done
 
-# ------------------------------------------------------------------
-
-# When called from JPRT the TESTDIRS variable is set to the jtreg tests to run
-ifdef TESTDIRS
-  TEST_SELECTION = $(TESTDIRS)
-endif
-
-ifdef CONCURRENCY
-  JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
-endif
-ifdef EXTRA_JTREG_OPTIONS
-  JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
-endif
-
-# Default JTREG to run
-JTREG = $(JT_HOME)/bin/jtreg
-# run in agentvm mode
-JTREG_BASIC_OPTIONS += -agentvm
-# Only run automatic tests
-JTREG_BASIC_OPTIONS += -a
-# Always turn on assertions
-JTREG_ASSERT_OPTION = -ea -esa
-JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION)
-# Report details on all failed or error tests, times too
-JTREG_BASIC_OPTIONS += -v:fail,error,time
-# Retain all files for failing tests
-JTREG_BASIC_OPTIONS += -retain:fail,error
-# Ignore tests are not run and completely silent about it
-JTREG_IGNORE_OPTION = -ignore:quiet
-JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
-# Multiple by 4 the timeout numbers
-JTREG_TIMEOUT_OPTION =  -timeoutFactor:4
-JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
-# Set the max memory for jtreg control vm
-JTREG_MEMORY_OPTION = -J-Xmx512m
-JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
-# Give tests access to JT_JAVA, see JDK-8141609
-JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
-# Set other vm and test options
-JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
-# Set the GC options for test vms
-#JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
-#JTREG_TEST_OPTIONS += $(JTREG_GC_OPTION)
-# Set the max memory for jtreg target test vms
-JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m
-JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
-
-# Make sure jtreg exists
-$(JTREG): $(JT_HOME)
-
-# Run jtreg
-jtreg_tests: prep $(PRODUCT_HOME) $(JTREG)
-	(                                                                    \
-	  ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)");                   \
-            export JT_HOME;                                                  \
-            $(shell $(GETMIXEDPATH) "$(JTREG)")                              \
-              $(JTREG_BASIC_OPTIONS)                                         \
-              -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport")  \
-              -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork")    \
-              -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                \
-              $(JTREG_NATIVE_PATH)                                           \
-              $(JTREG_FAILURE_HANDLER_OPTIONS)                               \
-              $(JTREG_EXCLUSIONS)                                            \
-              $(JTREG_TEST_OPTIONS)                                          \
-              $(TEST_SELECTION)                                                    \
-	  ) ;                                                                \
-	  $(BUNDLE_UP_AND_EXIT)                                              \
-	) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT)
-
-PHONY_LIST += jtreg_tests
-
-################################################################
-
-# Phony targets (e.g. these are not filenames)
-.PHONY: all clean prep $(PHONY_LIST)
-
-################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/TestCommon.gmk	Tue Dec 13 02:04:23 2016 +0100
@@ -0,0 +1,422 @@
+#
+# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# 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.
+#
+
+#
+# Common logic to run various tests for a component, to be included by the
+# component specific test makefiles.
+#
+
+# Default values for some properties that can be overridden by components.
+USE_JTREG_VERSION ?= 4.2
+JTREG_VM_TYPE ?= -agentvm
+USE_JTREG_ASSERT ?= true
+LIMIT_JTREG_VM_MEMORY ?= true
+
+.DEFAULT : all
+
+# Empty these to get rid of some default rules
+.SUFFIXES:
+.SUFFIXES: .java
+CO=
+GET=
+
+# Utilities used
+AWK       = awk
+CAT       = cat
+CD        = cd
+CHMOD     = chmod
+CP        = cp
+CUT       = cut
+DIRNAME   = dirname
+ECHO      = echo
+EGREP     = egrep
+EXPAND    = expand
+FIND      = find
+MKDIR     = mkdir
+PWD       = pwd
+RM        = rm -f
+SED       = sed
+SORT      = sort
+TEE       = tee
+UNAME     = uname
+UNIQ      = uniq
+WC        = wc
+ZIPEXE    = zip
+
+# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
+UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
+
+# Commands to run on paths to make mixed paths for java on windows
+ifeq ($(findstring CYGWIN,$(UNAME_S)), CYGWIN)
+  # Location of developer shared files
+  SLASH_JAVA = J:
+  GETMIXEDPATH = cygpath -m
+  PLATFORM = windows
+else
+  # Location of developer shared files
+  SLASH_JAVA = /java
+  GETMIXEDPATH = $(ECHO)
+  PLATFORM = unix # we only care about windows or bsd.
+  ifeq ($(UNAME_S), Darwin)
+    PLATFORM = bsd
+  endif
+  ifeq ($(findstring BSD,$(UNAME_S)), BSD)
+    PLATFORM = bsd
+  endif
+endif
+
+ifdef ALT_SLASH_JAVA
+  SLASH_JAVA = $(ALT_SLASH_JAVA)
+endif
+
+# Root of this test area (important to use full paths in some places)
+TEST_ROOT := $(shell $(PWD))
+
+# Root of all test results
+ifdef TEST_OUTPUT_DIR
+  $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg)
+  ABS_TEST_OUTPUT_DIR := \
+    $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD))
+else
+  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)
+endif
+
+# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
+ifndef PRODUCT_HOME
+  # Try to use images/jdk if it exists
+  ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/jdk
+  PRODUCT_HOME :=                               \
+    $(shell                                     \
+      if [ -d $(ABS_JDK_IMAGE) ] ; then         \
+         $(ECHO) "$(ABS_JDK_IMAGE)";            \
+       else                                     \
+         $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)";  \
+       fi)
+  PRODUCT_HOME := $(PRODUCT_HOME)
+endif
+
+# Expect JPRT to set JAVA_ARGS (e.g. -server etc.)
+ifdef JAVA_ARGS
+  JAVA_OPTIONS := $(JAVA_ARGS)
+else
+  JAVA_OPTIONS :=
+endif
+
+# Expect JPRT to set JPRT_PRODUCT_ARGS (e.g. -server etc.)
+#   Should be passed into 'java' only.
+#   Could include: -d64 -server -client OR any java option
+ifdef JPRT_PRODUCT_ARGS
+  JAVA_ARGS = $(JPRT_PRODUCT_ARGS)
+endif
+
+# Expect JPRT to set JPRT_PRODUCT_VM_ARGS (e.g. -Xcomp etc.)
+#   Should be passed into anything running the vm (java, javac, javadoc, ...).
+ifdef JPRT_PRODUCT_VM_ARGS
+  JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS)
+endif
+
+ifneq ($(NATIVE_TEST_PATH), )
+  # jtreg -nativepath <dir>
+  #
+  # Local make tests will be TEST_IMAGE_DIR and JPRT with jprt.use.reg.test.bundle=true
+  # should be JPRT_TESTNATIVE_PATH
+  ifdef TEST_IMAGE_DIR
+    TESTNATIVE_DIR = $(TEST_IMAGE_DIR)
+  else ifdef JPRT_TESTNATIVE_PATH
+    TESTNATIVE_DIR = $(JPRT_TESTNATIVE_PATH)
+  endif
+  ifdef TESTNATIVE_DIR
+    JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/$(NATIVE_TEST_PATH)")
+  endif
+endif
+
+ifeq ($(USE_FAILURE_HANDLER), true)
+  # jtreg failure handler config
+  ifeq ($(FAILURE_HANDLER_DIR), )
+    ifneq ($(TESTNATIVE_DIR), )
+      FAILURE_HANDLER_DIR := $(TESTNATIVE_DIR)/failure_handler
+    endif
+  endif
+  ifneq ($(FAILURE_HANDLER_DIR), )
+    FAILURE_HANDLER_DIR_MIXED := $(shell $(GETMIXEDPATH) "$(FAILURE_HANDLER_DIR)")
+    JTREG_FAILURE_HANDLER_OPTIONS := \
+        -timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
+        -observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
+        -timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \
+        -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver \
+        -timeoutHandlerTimeout:0
+  ifeq ($(PLATFORM), windows)
+      JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)"
+    endif
+  endif
+endif
+
+# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
+ifdef JPRT_ARCHIVE_BUNDLE
+  ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
+else
+  ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
+endif
+
+# How to create the test bundle (pass or fail, we want to create this)
+#   Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
+ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`     \
+	           && $(CD) $(ABS_TEST_OUTPUT_DIR)             \
+	           && $(CHMOD) -R a+r . \
+	           && $(ZIPEXE) -q -r $(ARCHIVE_BUNDLE) . )
+
+# important results files
+SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
+STATS_TXT_NAME = Stats.txt
+STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)")
+RUNLIST   = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt")
+PASSLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt")
+FAILLIST  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt")
+EXITCODE  = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt")
+
+TESTEXIT = \
+  if [ ! -s $(EXITCODE) ] ; then \
+    $(ECHO) "ERROR: EXITCODE file not filled in."; \
+    $(ECHO) "1" > $(EXITCODE); \
+  fi ; \
+  testExitCode=`$(CAT) $(EXITCODE)`; \
+  $(ECHO) "EXIT CODE: $${testExitCode}"; \
+  exit $${testExitCode}
+
+ifeq ($(TREAT_EXIT_CODE_1_AS_0), true)
+  ADJUST_EXIT_CODE := \
+  if [ $${jtregExitCode} = 1 ] ; then \
+    jtregExitCode=0; \
+  fi
+else
+  # colon is the shell no-op
+  ADJUST_EXIT_CODE := :
+endif
+
+BUNDLE_UP_AND_EXIT = \
+( \
+  jtregExitCode=$$? && \
+  _summary="$(SUMMARY_TXT)"; \
+  $(ADJUST_EXIT_CODE) ; \
+  $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
+  $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
+  if [ -r "$${_summary}" ] ; then \
+    $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
+    $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
+    $(EGREP) ' Passed\.' $(RUNLIST) \
+      | $(EGREP) -v ' Error\.' \
+      | $(EGREP) -v ' Failed\.' > $(PASSLIST); \
+    ( $(EGREP) ' Failed\.' $(RUNLIST); \
+      $(EGREP) ' Error\.' $(RUNLIST); \
+      $(EGREP) -v ' Passed\.' $(RUNLIST) ) \
+      | $(SORT) | $(UNIQ) > $(FAILLIST); \
+    if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \
+      $(EXPAND) $(FAILLIST) \
+        | $(CUT) -d' ' -f1 \
+        | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \
+      if [ $${jtregExitCode} = 0 ] ; then \
+        jtregExitCode=1; \
+      fi; \
+    fi; \
+    runc="`$(CAT) $(RUNLIST)      | $(WC) -l | $(AWK) '{print $$1;}'`"; \
+    passc="`$(CAT) $(PASSLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
+    failc="`$(CAT) $(FAILLIST)    | $(WC) -l | $(AWK) '{print $$1;}'`"; \
+    exclc="FIXME CODETOOLS-7900176"; \
+    $(ECHO) "TEST STATS: name=$(UNIQUE_DIR)  run=$${runc}  pass=$${passc}  fail=$${failc}" \
+      >> $(STATS_TXT); \
+  else \
+    $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
+  fi; \
+  if [ -f $(STATS_TXT) ] ; then \
+    $(CAT) $(STATS_TXT); \
+  fi; \
+  $(ZIP_UP_RESULTS) ; \
+  $(TESTEXIT) \
+)
+
+################################################################
+
+# Prep for output
+# Change execute permissions on shared library files.
+# Files in repositories should never have execute permissions, but
+# there are some tests that have pre-built shared libraries, and these
+# windows dll files must have execute permission. Adding execute
+# permission may happen automatically on windows when using certain
+# versions of mercurial but it cannot be guaranteed. And blindly
+# adding execute permission might be seen as a mercurial 'change', so
+# we avoid adding execute permission to repository files. But testing
+# from a plain source tree needs the chmod a+rx. Applying the chmod to
+# all shared libraries not just dll files. And with CYGWIN and sshd
+# service, you may need CYGWIN=ntsec for this to work.
+prep:
+	@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
+	@$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`
+	@if [ ! -d $(TEST_ROOT)/../.hg ] ; then                                   \
+	  $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \)  \
+	        -exec $(CHMOD) a+rx {} \; ;                                       \
+	fi
+
+ifeq ($(CLEAN_BEFORE_PREP), true)
+prep: clean
+
+endif
+
+# Cleanup
+clean:
+	@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
+	@$(RM) $(ARCHIVE_BUNDLE)
+
+################################################################
+
+# jtreg tests
+
+# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
+ifndef JT_HOME
+  JT_HOME = $(SLASH_JAVA)/re/jtreg/$(USE_JTREG_VERSION)/promoted/latest/binaries/jtreg
+  ifdef JPRT_JTREG_HOME
+    JT_HOME = $(JPRT_JTREG_HOME)
+  endif
+endif
+
+# Problematic tests to be excluded
+PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt))
+
+# Create exclude list for this platform and arch
+ifdef NO_EXCLUDES
+  JTREG_EXCLUSIONS =
+else
+  JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%)
+endif
+
+# convert list of directories to dos paths
+define MixedDirs
+$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}"))
+endef
+
+# ------------------------------------------------------------------
+
+# When called from JPRT the TESTDIRS variable is set to the jtreg tests to run
+ifdef TESTDIRS
+  TEST_SELECTION = $(TESTDIRS)
+endif
+
+ifdef CONCURRENCY
+  JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
+endif
+ifdef EXTRA_JTREG_OPTIONS
+  JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
+endif
+
+# Default JTREG to run
+JTREG = $(JT_HOME)/bin/jtreg
+# run in agentvm/othervm mode
+JTREG_BASIC_OPTIONS += $(JTREG_VM_TYPE)
+# Only run automatic tests
+JTREG_BASIC_OPTIONS += -a
+# Always turn on assertions
+ifeq ($(USE_JTREG_ASSERT), true)
+  JTREG_ASSERT_OPTION = -ea -esa
+endif
+JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION)
+# jtreg verbosity setting
+# Default is to report details on all failed or error tests, times too
+JTREG_VERBOSE ?= fail,error,time
+JTREG_BASIC_OPTIONS += $(if $(JTREG_VERBOSE),-v:$(JTREG_VERBOSE))
+# Retain all files for failing tests
+JTREG_BASIC_OPTIONS += -retain:fail,error
+# Ignore tests are not run and completely silent about it
+JTREG_IGNORE_OPTION = -ignore:quiet
+JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
+# Multiply by 4 the timeout factor
+JTREG_TIMEOUT_OPTION =  -timeoutFactor:4
+JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
+ifeq ($(LIMIT_JTREG_VM_MEMORY), true)
+  # Set the max memory for jtreg control vm
+  JTREG_MEMORY_OPTION = -J-Xmx512m
+  JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
+  # Set the max memory for jtreg target test vms
+  JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m
+  JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
+endif
+# Give tests access to JT_JAVA, see JDK-8141609
+JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
+# Set other vm and test options
+JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)
+
+ifeq ($(IGNORE_MARKED_TESTS), true)
+  # Option to tell jtreg to not run tests marked with "ignore"
+  ifeq ($(PLATFORM), windows)
+    JTREG_KEY_OPTION = -k:!ignore
+  else
+    JTREG_KEY_OPTION = -k:\!ignore
+  endif
+  JTREG_BASIC_OPTIONS += $(JTREG_KEY_OPTION)
+endif
+
+# Make sure jtreg exists
+ifeq ($(USE_WINDOWS_EXISTENCE_CHECK), true)
+  jtreg_exists:
+	test -d $(shell $(GETMIXEDPATH) "$(JT_HOME)")
+	test -f $(shell $(GETMIXEDPATH) "$(JTREG)")
+
+else
+  jtreg_exists: $(JT_HOME)
+endif
+PHONY_LIST += jtreg_exists
+
+# Run jtreg
+jtreg_tests: prep jtreg_exists $(PRODUCT_HOME)
+	(                                                                    \
+	  ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)");                   \
+	    export JT_HOME;                                                  \
+	    $(shell $(GETMIXEDPATH) "$(JTREG)")                              \
+	      $(JTREG_BASIC_OPTIONS)                                         \
+	      -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport")  \
+	      -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork")    \
+	      -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                \
+	      $(JTREG_NATIVE_PATH)                                           \
+	      $(JTREG_FAILURE_HANDLER_OPTIONS)                               \
+	      $(JTREG_EXCLUSIONS)                                            \
+	      $(JTREG_TEST_OPTIONS)                                          \
+	      $(TEST_SELECTION)                                              \
+	  ) ;                                                                \
+	  $(BUNDLE_UP_AND_EXIT)                                              \
+	) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT)
+
+PHONY_LIST += jtreg_tests
+
+################################################################
+
+# Phony targets (e.g. these are not filenames)
+.PHONY: all clean prep $(PHONY_LIST)
+
+################################################################