Merge
authortwisti
Tue, 22 Dec 2015 13:41:12 -0800
changeset 35257 87ae1d0f6948
parent 35256 f0d65657e313 (current diff)
parent 35250 abe1866e51e3 (diff)
child 35258 5b3c803c2d1e
Merge
jdk/src/java.base/share/classes/java/lang/ref/Reference.java
jdk/src/java.base/share/classes/sun/misc/BASE64Decoder.java
jdk/src/java.base/share/classes/sun/misc/BASE64Encoder.java
jdk/src/java.base/share/classes/sun/misc/CharacterDecoder.java
jdk/src/java.base/share/classes/sun/misc/CharacterEncoder.java
jdk/src/java.base/share/classes/sun/misc/HexDumpEncoder.java
jdk/src/java.base/share/classes/sun/misc/ProxyGenerator.java
jdk/src/java.base/share/classes/sun/misc/Queue.java
jdk/src/java.base/share/classes/sun/misc/Request.java
jdk/src/java.base/share/classes/sun/misc/RequestProcessor.java
jdk/src/java.base/share/classes/sun/misc/UCDecoder.java
jdk/src/java.base/share/classes/sun/misc/UCEncoder.java
jdk/src/java.base/share/classes/sun/misc/UUDecoder.java
jdk/src/java.base/share/classes/sun/misc/UUEncoder.java
jdk/src/java.base/share/native/libzip/ZipFile.c
jdk/test/sun/misc/Encode/DecodeBuffer.java
jdk/test/sun/misc/Encode/Encode.java
jdk/test/sun/misc/Encode/GetBytes.java
--- a/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -339,3 +339,4 @@
 25a2cab05cfbe6034b71d9e72d64c65b0572ce63 jdk9-b94
 5ac6287ec71aafe021cc839d8bc828108d23aaba jdk-9+95
 139f19d70350238e15e107945cea75082b6380b3 jdk-9+96
+4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97
--- a/.hgtags-top-repo	Fri Dec 18 10:00:55 2015 -0800
+++ b/.hgtags-top-repo	Tue Dec 22 13:41:12 2015 -0800
@@ -339,3 +339,4 @@
 349488425abcaf3ff62f580007860b4b56875d10 jdk9-b94
 12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95
 5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
+75c3897541ecb52ee16d001ea605b12971df7303 jdk-9+97
--- a/corba/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/corba/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -339,3 +339,4 @@
 61e9f509be0f78f0961477960f372b0533214bb8 jdk9-b94
 fd038e8a16eec80d0d6b337d74a582790ed4b3ee jdk-9+95
 feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
+10a482b863582376d4ca229090334b23b05159fc jdk-9+97
--- a/hotspot/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/hotspot/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -499,3 +499,4 @@
 a22b7c80529f5f05c847e932e017456e83c46233 jdk9-b94
 0c79cf3cdf0904fc4a630b91b32904491e1ae430 jdk-9+95
 a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
+de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
--- a/jaxp/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/jaxp/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -339,3 +339,4 @@
 5e75b8a9c01bca09c56dec7539e44dc82090c7c2 jdk9-b94
 c8d0845877a811ab4350935892f826929359a3ff jdk-9+95
 1f3182529f2c474e5506955ccb3820cfa5822265 jdk-9+96
+9c107c050335d7ee63b2a8b38ca5d498f19713a2 jdk-9+97
--- a/jaxws/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/jaxws/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -342,3 +342,4 @@
 e8d15c61400c1682a7873e053d7b39efde0b79be jdk9-b94
 3e03ddaaac6585fa27e91596eb2a9a31e10bdcc9 jdk-9+95
 b55cebc47555293cf9c2aefb3bf63c56e847ab19 jdk-9+96
+7293db4716ee25b814e14f738b9acfb85700e3fa jdk-9+97
--- a/jdk/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -339,3 +339,4 @@
 559b626b01179420a94feb9c3d0f246970d2e3fa jdk9-b94
 8581faf0d474472e32f589bbc16db7eec912d83f jdk-9+95
 c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96
+fdd84b2265ddce7f50e084b7c8635189bba6f012 jdk-9+97
--- a/jdk/make/CompileDemos.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/CompileDemos.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -309,7 +309,7 @@
 
   ifeq ($$($1_TOOLCHAIN), TOOLCHAIN_LINK_CXX)
     # For C++, we also need some special treatment.
-    $1_LDFLAGS := $(LDFLAGS_CXX_JDK)
+    $1_LDFLAGS := $$(LDFLAGS_CXX_JDK)
     $1_LIBS := $(LIBCXX)
 
     ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc)
@@ -324,9 +324,9 @@
       OPTIMIZATION := LOW, \
       CFLAGS := $$($1_CFLAGS_INCLUDE) $$(CFLAGS_JDKLIB) $$(CFLAGS_DEBUG_SYMBOLS), \
       CXXFLAGS := $$($1_CXXFLAGS), \
-      LDFLAGS := $(filter-out -incremental:no -opt:ref, $(LDFLAGS_JDKLIB)) \
+      LDFLAGS := $(filter-out -incremental:no -opt:ref, $$(LDFLAGS_JDKLIB)) \
           $$($1_LDFLAGS), \
-      LDFLAGS_macosx := $(call SET_EXECUTABLE_ORIGIN), \
+      LDFLAGS_macosx := $$(call SET_EXECUTABLE_ORIGIN), \
       LIBS := $$($1_LIBS), \
       LIBS_solaris := -lc, \
       VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
--- a/jdk/make/launcher/Launcher-java.base.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/launcher/Launcher-java.base.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -127,8 +127,7 @@
           $(BUILD_JEXEC_INC), \
       CFLAGS_linux := -fPIC, \
       CFLAGS_solaris := -KPIC, \
-      LDFLAGS := $(LDFLAGS_JDKEXE) \
-          $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \
+      LDFLAGS := $(LDFLAGS_JDKEXE), \
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jexec_obj, \
       OUTPUT_DIR := $(BUILD_JEXEC_DST_DIR), \
       DEBUG_SYMBOLS := true, \
--- a/jdk/make/launcher/Launcher-jdk.pack200.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/launcher/Launcher-jdk.pack200.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -89,7 +89,6 @@
     MAPFILE := $(UNPACK_MAPFILE),\
     LDFLAGS := $(UNPACKEXE_ZIPOBJS) \
         $(LDFLAGS_JDKEXE) $(LDFLAGS_CXX_JDK) \
-        $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX)) \
         $(call SET_SHARED_LIBRARY_ORIGIN), \
     LIBS := $(UNPACKEXE_LIBS) $(LIBCXX), \
     LIBS_solaris :=  -lc, \
--- a/jdk/make/launcher/LauncherCommon.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/launcher/LauncherCommon.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -25,6 +25,12 @@
 
 include NativeCompilation.gmk
 
+# SetupNativeCompilation now supports debug symbols on macosx for hotspot.
+# Disable it here for the jdk binaries until we decide to enable them.
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  ENABLE_DEBUG_SYMBOLS := false
+endif
+
 # Prepare the find cache.
 $(eval $(call FillCacheFind, $(JDK_TOPDIR)/src/java.base/share/native/launcher))
 
@@ -180,15 +186,12 @@
       CFLAGS_linux := -fPIC, \
       CFLAGS_solaris := -KPIC -DHAVE_GETHRTIME, \
       CFLAGS_windows := $$($1_CFLAGS_windows), \
-      LDFLAGS := $(LDFLAGS_JDKEXE) \
+      LDFLAGS := $$(LDFLAGS_JDKEXE) \
           $$(ORIGIN_ARG) \
           $$($1_LDFLAGS), \
       LDFLAGS_linux := \
-          $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)) \
           -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)/jli, \
-      LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_NAME,$1), \
       LDFLAGS_solaris := $$($1_LDFLAGS_solaris) \
-          $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)) \
           -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)/jli, \
       MAPFILE := $$($1_MAPFILE), \
       LIBS := $(JDKEXE_LIBS) $$($1_LIBS), \
--- a/jdk/make/lib/Awt2dLibraries.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -683,7 +683,7 @@
     WARNINGS_AS_ERRORS_gcc := false, \
     WARNINGS_AS_ERRORS_solstudio := false, \
     MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \
-    LDFLAGS := $(subst -Xlinker -z -Xlinker defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \
+    LDFLAGS := $(subst -Wl$(COMMA)-z$(COMMA)defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \
         $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
     LDFLAGS_macosx := -undefined dynamic_lookup, \
@@ -799,7 +799,7 @@
       LDFLAGS := $(LDFLAGS_JDKLIB) \
           $(call SET_SHARED_LIBRARY_ORIGIN), \
       LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
-      LDFLAGS_macosx := -Xlinker -rpath -Xlinker @loader_path, \
+      LDFLAGS_macosx := -Wl$(COMMA)-rpath$(COMMA)@loader_path, \
       LIBS_unix := $(JAWT_LIBS) $(JDKLIB_LIBS), \
       LIBS_solaris := $(X_LIBS) -lXrender, \
       LIBS_macosx := -framework Cocoa, \
@@ -1034,7 +1034,7 @@
           -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop,  \
       LDFLAGS := $(LDFLAGS_JDKLIB) \
           $(call SET_SHARED_LIBRARY_ORIGIN) \
-          -Xlinker -rpath -Xlinker @loader_path \
+          -Wl$(COMMA)-rpath$(COMMA)@loader_path \
           -L$(INSTALL_LIBRARIES_HERE), \
       LIBS := -lawt -losxapp -lawt_lwawt \
           -framework Cocoa \
--- a/jdk/make/lib/Lib-java.instrument.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/lib/Lib-java.instrument.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -65,7 +65,7 @@
         -L$(call FindLibDirForModule, java.base)/jli, \
     LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/jli) \
         -L$(call FindLibDirForModule, java.base)/jli, \
-    LDFLAGS_macosx := -Xlinker -all_load $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a, \
+    LDFLAGS_macosx := -Wl$(COMMA)-all_load, \
     LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \
     LDFLAGS_windows := -export:Agent_OnAttach, \
     LIBS := $(JDKLIB_LIBS), \
@@ -74,7 +74,8 @@
     LIBS_solaris := -ljli $(LIBDL), \
     LIBS_aix := -liconv -ljli_static $(LIBDL), \
     LIBS_macosx := -liconv -framework Cocoa -framework Security \
-        -framework ApplicationServices, \
+        -framework ApplicationServices \
+        $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a, \
     LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib \
         $(SUPPORT_OUTPUTDIR)/native/java.base/jli_static.lib, \
     VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
--- a/jdk/make/lib/LibCommon.gmk	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/lib/LibCommon.gmk	Tue Dec 22 13:41:12 2015 -0800
@@ -46,6 +46,12 @@
   endif
 endif
 
+# SetupNativeCompilation now supports debug symbols on macosx for hotspot.
+# Disable it here for the jdk libraries until we decide to enable them.
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  ENABLE_DEBUG_SYMBOLS := false
+endif
+
 ################################################################################
 # Find the default set of src dirs for a native library.
 # Param 1 - module name
--- a/jdk/make/mapfiles/libzip/mapfile-vers	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/mapfiles/libzip/mapfile-vers	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 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
@@ -27,7 +27,6 @@
 
 SUNWprivate_1.1 {
 	global:
-		Java_java_util_jar_JarFile_getMetaInfEntryNames;
 		Java_java_util_zip_Adler32_update;
 		Java_java_util_zip_Adler32_updateBytes;
 		Java_java_util_zip_Adler32_updateByteBuffer;
@@ -48,25 +47,6 @@
 		Java_java_util_zip_Inflater_initIDs;
 		Java_java_util_zip_Inflater_reset;
 		Java_java_util_zip_Inflater_setDictionary;
-		Java_java_util_zip_ZipFile_close;
-		Java_java_util_zip_ZipFile_getCommentBytes;
-		Java_java_util_zip_ZipFile_freeEntry;
-		Java_java_util_zip_ZipFile_getEntry;
-		Java_java_util_zip_ZipFile_getEntryBytes;
-		Java_java_util_zip_ZipFile_getEntryCrc;
-		Java_java_util_zip_ZipFile_getEntryCSize;
-		Java_java_util_zip_ZipFile_getEntryFlag;
-		Java_java_util_zip_ZipFile_getEntryMethod;
-		Java_java_util_zip_ZipFile_getEntrySize;
-		Java_java_util_zip_ZipFile_getEntryTime;
-		Java_java_util_zip_ZipFile_getNextEntry;
-		Java_java_util_zip_ZipFile_getZipMessage;
-		Java_java_util_zip_ZipFile_getTotal;
-		Java_java_util_zip_ZipFile_initIDs;
-		Java_java_util_zip_ZipFile_open;
-		Java_java_util_zip_ZipFile_read;
-		Java_java_util_zip_ZipFile_startsWithLOC;
-
 		ZIP_Close;
 		ZIP_CRC32;
 		ZIP_FindEntry;
--- a/jdk/make/mapfiles/libzip/reorder-sparc	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/mapfiles/libzip/reorder-sparc	Tue Dec 22 13:41:12 2015 -0800
@@ -16,30 +16,14 @@
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
-text: .text%Java_java_util_zip_ZipFile_initIDs;
-text: .text%Java_java_util_zip_ZipFile_open;
-text: .text%Java_java_util_zip_ZipFile_getTotal;
-text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
-text: .text%Java_java_util_zip_ZipFile_getEntry;
-text: .text%Java_java_util_zip_ZipFile_freeEntry;
-text: .text%Java_java_util_zip_ZipFile_getEntryTime;
-text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
-text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
-text: .text%Java_java_util_zip_ZipFile_getEntrySize;
-text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
-text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
-text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
 text: .text%Java_java_util_zip_Inflater_initIDs;
 text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
 text: .text%zcalloc;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
-text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
-text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
 text: .text%Java_java_util_zip_Inflater_reset;
 text: .text%Java_java_util_zip_Inflater_end;
 text: .text%inflateEnd;
-text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
--- a/jdk/make/mapfiles/libzip/reorder-sparcv9	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/mapfiles/libzip/reorder-sparcv9	Tue Dec 22 13:41:12 2015 -0800
@@ -15,19 +15,6 @@
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
-text: .text%Java_java_util_zip_ZipFile_initIDs;
-text: .text%Java_java_util_zip_ZipFile_open;
-text: .text%Java_java_util_zip_ZipFile_getTotal;
-text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
-text: .text%Java_java_util_zip_ZipFile_getEntry;
-text: .text%Java_java_util_zip_ZipFile_freeEntry;
-text: .text%Java_java_util_zip_ZipFile_getEntryTime;
-text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
-text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
-text: .text%Java_java_util_zip_ZipFile_getEntrySize;
-text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
-text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
-text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
 text: .text%Java_java_util_zip_Inflater_initIDs;
 text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
@@ -35,7 +22,6 @@
 text: .text%inflateReset;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
 text: .text%inflate;
-text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
 text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
@@ -43,6 +29,5 @@
 text: .text%InflateFully;
 text: .text%inflateEnd;
 text: .text%Java_java_util_zip_Inflater_reset;
-text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
 text: .text%Java_java_util_zip_Inflater_end;
--- a/jdk/make/mapfiles/libzip/reorder-x86	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/make/mapfiles/libzip/reorder-x86	Tue Dec 22 13:41:12 2015 -0800
@@ -16,34 +16,16 @@
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
-text: .text%Java_java_util_zip_ZipFile_initIDs;
-text: .text%Java_java_util_zip_ZipFile_open;
-text: .text%Java_java_util_zip_ZipFile_getTotal;
-text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
-text: .text%Java_java_util_zip_ZipFile_getEntry;
-text: .text%Java_java_util_zip_ZipFile_freeEntry;
-text: .text%Java_java_util_zip_ZipFile_getEntryTime;
-text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
-text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
-text: .text%Java_java_util_zip_ZipFile_getEntrySize;
-text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
-text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
-text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
-text: .text%Java_java_util_zip_Inflater_initIDs;
-text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
 text: .text%zcalloc;
 text: .text%inflateReset;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
 text: .text%inflate;
-text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
-text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
 text: .text%ZIP_ReadEntry;
 text: .text%InflateFully;
 text: .text%inflateEnd;
 text: .text%Java_java_util_zip_Inflater_reset;
-text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
 text: .text%Java_java_util_zip_Inflater_end;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java	Tue Dec 22 13:41:12 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.io.*;
 import sun.security.util.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
 import javax.crypto.spec.IvParameterSpec;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,7 @@
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
 import javax.crypto.spec.GCMParameterSpec;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 /**
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBEParameters.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBEParameters.java	Tue Dec 22 13:41:12 2015 -0800
@@ -31,7 +31,7 @@
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
 import javax.crypto.spec.PBEParameterSpec;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 import java.security.spec.InvalidParameterSpecException;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.PBEParameterSpec;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 /**
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,7 @@
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
 import javax.crypto.spec.RC2ParameterSpec;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 /**
--- a/jdk/src/java.base/share/classes/com/sun/security/ntlm/NTLM.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/security/ntlm/NTLM.java	Tue Dec 22 13:41:12 2015 -0800
@@ -118,7 +118,7 @@
     public void debug(byte[] bytes) {
         if (DEBUG) {
             try {
-                new sun.misc.HexDumpEncoder().encodeBuffer(bytes, System.out);
+                new sun.security.util.HexDumpEncoder().encodeBuffer(bytes, System.out);
             } catch (IOException ioe) {
                 // Impossible
             }
--- a/jdk/src/java.base/share/classes/java/io/CharArrayReader.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/CharArrayReader.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -225,9 +225,12 @@
      * Closes the stream and releases any system resources associated with
      * it.  Once the stream has been closed, further read(), ready(),
      * mark(), reset(), or skip() invocations will throw an IOException.
-     * Closing a previously closed stream has no effect.
+     * Closing a previously closed stream has no effect. This method will block
+     * while there is another thread blocking on the reader.
      */
     public void close() {
-        buf = null;
+        synchronized (lock) {
+            buf = null;
+        }
     }
 }
--- a/jdk/src/java.base/share/classes/java/io/PushbackReader.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/PushbackReader.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -241,13 +241,16 @@
      * Closes the stream and releases any system resources associated with
      * it. Once the stream has been closed, further read(),
      * unread(), ready(), or skip() invocations will throw an IOException.
-     * Closing a previously closed stream has no effect.
+     * Closing a previously closed stream has no effect. This method will block
+     * while there is another thread blocking on the reader.
      *
      * @exception  IOException  If an I/O error occurs
      */
     public void close() throws IOException {
-        super.close();
-        buf = null;
+        synchronized (lock) {
+            super.close();
+            buf = null;
+        }
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/StringReader.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/StringReader.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -194,9 +194,12 @@
      * Closes the stream and releases any system resources associated with
      * it. Once the stream has been closed, further read(),
      * ready(), mark(), or reset() invocations will throw an IOException.
-     * Closing a previously closed stream has no effect.
+     * Closing a previously closed stream has no effect. This method will block
+     * while there is another thread blocking on the reader.
      */
     public void close() {
-        str = null;
+        synchronized (lock) {
+            str = null;
+        }
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/InheritableThreadLocal.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/InheritableThreadLocal.java	Tue Dec 22 13:41:12 2015 -0800
@@ -40,6 +40,11 @@
  * maintained in the variable (e.g., User ID, Transaction ID) must be
  * automatically transmitted to any child threads that are created.
  *
+ * <p>Note: During the creation of a new {@link
+ * Thread#Thread(ThreadGroup,Runnable,String,long,boolean) thread}, it is
+ * possible to <i>opt out</i> of receiving initial values for inheritable
+ * thread-local variables.
+ *
  * @author  Josh Bloch and Doug Lea
  * @see     ThreadLocal
  * @since   1.2
--- a/jdk/src/java.base/share/classes/java/lang/StackWalker.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java	Tue Dec 22 13:41:12 2015 -0800
@@ -304,8 +304,8 @@
     }
 
     /**
-     * Returns a {@code StackWalker} instance with the given {@ocde options} specifying
-     * the stack frame information it can access. If the given {@ocde options}
+     * Returns a {@code StackWalker} instance with the given {@code options} specifying
+     * the stack frame information it can access. If the given {@code options}
      * is empty, this {@code StackWalker} is configured to skip all
      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
--- a/jdk/src/java.base/share/classes/java/lang/StringUTF16.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/StringUTF16.java	Tue Dec 22 13:41:12 2015 -0800
@@ -120,7 +120,8 @@
     public static byte[] toBytes(char[] value, int off, int len) {
         byte[] val = newBytesFor(len);
         for (int i = 0; i < len; i++) {
-            putChar(val, i, value[off++]);
+            putChar(val, i, value[off]);
+            off++;
         }
         return val;
     }
@@ -145,11 +146,14 @@
     @HotSpotIntrinsicCandidate
     private static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) {
         for (int i = 0; i < len; i++) {
-            int c = src[srcOff++];
-            if (c >>> 8 != 0) {
-                return 0;
+            char c = src[srcOff];
+            if (c > 0xFF) {
+                len = 0;
+                break;
             }
-            dst[dstOff++] = (byte)c;
+            dst[dstOff] = (byte)c;
+            srcOff++;
+            dstOff++;
         }
         return len;
     }
@@ -160,11 +164,14 @@
         // We need a range check here because 'getChar' has no checks
         checkBoundsOffCount(srcOff, len, src.length);
         for (int i = 0; i < len; i++) {
-            int c = getChar(src, srcOff++);
-            if (c >>> 8 != 0) {
-                return 0;
+            char c = getChar(src, srcOff);
+            if (c > 0xFF) {
+                len = 0;
+                break;
             }
-            dst[dstOff++] = (byte)c;
+            dst[dstOff] = (byte)c;
+            srcOff++;
+            dstOff++;
         }
         return len;
     }
@@ -581,7 +588,7 @@
             bits |= cp;
             putChar(result, i, cp);
         }
-        if (bits >>> 8 != 0) {
+        if (bits > 0xFF) {
             return new String(result, UTF16);
         } else {
             return newString(result, 0, len);
@@ -678,7 +685,7 @@
             bits |= cp;
             putChar(result, i, cp);
         }
-        if (bits >>> 8 != 0) {
+        if (bits > 0xFF) {
             return new String(result, UTF16);
         } else {
             return newString(result, 0, len);
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java	Tue Dec 22 13:41:12 2015 -0800
@@ -344,11 +344,11 @@
 
     /**
      * Initializes a Thread with the current AccessControlContext.
-     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
+     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean)
      */
     private void init(ThreadGroup g, Runnable target, String name,
                       long stackSize) {
-        init(g, target, name, stackSize, null);
+        init(g, target, name, stackSize, null, true);
     }
 
     /**
@@ -361,9 +361,12 @@
      *        zero to indicate that this parameter is to be ignored.
      * @param acc the AccessControlContext to inherit, or
      *            AccessController.getContext() if null
+     * @param inheritThreadLocals if {@code true}, inherit initial values for
+     *            inheritable thread-locals from the constructing thread
      */
     private void init(ThreadGroup g, Runnable target, String name,
-                      long stackSize, AccessControlContext acc) {
+                      long stackSize, AccessControlContext acc,
+                      boolean inheritThreadLocals) {
         if (name == null) {
             throw new NullPointerException("name cannot be null");
         }
@@ -414,7 +417,7 @@
                 acc != null ? acc : AccessController.getContext();
         this.target = target;
         setPriority(priority);
-        if (parent.inheritableThreadLocals != null)
+        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
             this.inheritableThreadLocals =
                 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
         /* Stash the specified stack size in case the VM cares */
@@ -468,7 +471,7 @@
      * This is not a public constructor.
      */
     Thread(Runnable target, AccessControlContext acc) {
-        init(null, target, "Thread-" + nextThreadNum(), 0, acc);
+        init(null, target, "Thread-" + nextThreadNum(), 0, acc, true);
     }
 
     /**
@@ -678,6 +681,62 @@
     }
 
     /**
+     * Allocates a new {@code Thread} object so that it has {@code target}
+     * as its run object, has the specified {@code name} as its name,
+     * belongs to the thread group referred to by {@code group}, has
+     * the specified {@code stackSize}, and inherits initial values for
+     * {@linkplain InheritableThreadLocal inheritable thread-local} variables
+     * if {@code inheritThreadLocals} is {@code true}.
+     *
+     * <p> This constructor is identical to {@link
+     * #Thread(ThreadGroup,Runnable,String,long)} with the added ability to
+     * suppress, or not, the inheriting of initial values for inheritable
+     * thread-local variables from the constructing thread. This allows for
+     * finer grain control over inheritable thread-locals. Care must be taken
+     * when passing a value of {@code false} for {@code inheritThreadLocals},
+     * as it may lead to unexpected behavior if the new thread executes code
+     * that expects a specific thread-local value to be inherited.
+     *
+     * <p> Specifying a value of {@code true} for the {@code inheritThreadLocals}
+     * parameter will cause this constructor to behave exactly like the
+     * {@code Thread(ThreadGroup, Runnable, String, long)} constructor.
+     *
+     * @param  group
+     *         the thread group. If {@code null} and there is a security
+     *         manager, the group is determined by {@linkplain
+     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+     *         If there is not a security manager or {@code
+     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
+     *         is set to the current thread's thread group.
+     *
+     * @param  target
+     *         the object whose {@code run} method is invoked when this thread
+     *         is started. If {@code null}, this thread's run method is invoked.
+     *
+     * @param  name
+     *         the name of the new thread
+     *
+     * @param  stackSize
+     *         the desired stack size for the new thread, or zero to indicate
+     *         that this parameter is to be ignored
+     *
+     * @param  inheritThreadLocals
+     *         if {@code true}, inherit initial values for inheritable
+     *         thread-locals from the constructing thread, otherwise no initial
+     *         values are inherited
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot create a thread in the specified
+     *          thread group
+     *
+     * @since 9
+     */
+    public Thread(ThreadGroup group, Runnable target, String name,
+                  long stackSize, boolean inheritThreadLocals) {
+        init(group, target, name, stackSize, null, inheritThreadLocals);
+    }
+
+    /**
      * Causes this thread to begin execution; the Java Virtual Machine
      * calls the <code>run</code> method of this thread.
      * <p>
--- a/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,7 +29,6 @@
 import java.security.AccessController;
 import jdk.internal.misc.JavaLangAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.ManagedLocalsThread;
 import sun.misc.VM;
 
 final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
@@ -131,7 +130,7 @@
                     for (ThreadGroup tgn = tg;
                          tgn != null;
                          tg = tgn, tgn = tg.getParent());
-                    Thread sft = new ManagedLocalsThread(tg, proc, "Secondary finalizer");
+                    Thread sft = new Thread(tg, proc, "Secondary finalizer", 0, false);
                     sft.start();
                     try {
                         sft.join();
@@ -190,10 +189,10 @@
                 }}});
     }
 
-    private static class FinalizerThread extends ManagedLocalsThread {
+    private static class FinalizerThread extends Thread {
         private volatile boolean running;
         FinalizerThread(ThreadGroup g) {
-            super(g, "Finalizer");
+            super(g, null, "Finalizer", 0, false);
         }
         public void run() {
             // in case of recursive call to run()
--- a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,6 @@
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.JavaLangRefAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Abstract base class for reference objects.  This class defines the
@@ -129,7 +128,7 @@
 
     /* High-priority thread to enqueue pending References
      */
-    private static class ReferenceHandler extends ManagedLocalsThread {
+    private static class ReferenceHandler extends Thread {
 
         private static void ensureClassInitialized(Class<?> clazz) {
             try {
@@ -148,7 +147,7 @@
         }
 
         ReferenceHandler(ThreadGroup g, String name) {
-            super(g, name);
+            super(g, null, name, 0, false);
         }
 
         public void run() {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedArrayType.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedArrayType.java	Tue Dec 22 13:41:12 2015 -0800
@@ -42,4 +42,19 @@
      * @see GenericArrayType#getGenericComponentType()
      */
     AnnotatedType  getAnnotatedGenericComponentType();
+
+    /**
+     * Returns the potentially annotated type that this type is a member of, if
+     * this type represents a nested type. For example, if this type is
+     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+     *
+     * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
+     *     of {@code AnnotatedArrayType}.
+     *
+     * @return {@code null}
+     *
+     * @since 1.9
+     */
+    @Override
+    AnnotatedType getAnnotatedOwnerType();
 }
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedParameterizedType.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedParameterizedType.java	Tue Dec 22 13:41:12 2015 -0800
@@ -41,4 +41,26 @@
      * @see ParameterizedType#getActualTypeArguments()
      */
     AnnotatedType[] getAnnotatedActualTypeArguments();
+
+    /**
+     * Returns the potentially annotated type that this type is a member of, if
+     * this type represents a nested type. For example, if this type is
+     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+     *
+     * <p>Returns {@code null} if this {@code AnnotatedType} represents a
+     *     top-level type, or a local or anonymous class, or a primitive type, or
+     *     void.
+     *
+     * @return an {@code AnnotatedType} object representing the potentially
+     *     annotated type that this type is a member of, or {@code null}
+     * @throws TypeNotPresentException if the owner type
+     *     refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if the owner type
+     *     refers to a parameterized type that cannot be instantiated
+     *     for any reason
+     *
+     * @since 1.9
+     */
+    @Override
+    AnnotatedType getAnnotatedOwnerType();
 }
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java	Tue Dec 22 13:41:12 2015 -0800
@@ -36,6 +36,37 @@
 public interface AnnotatedType extends AnnotatedElement {
 
     /**
+     * Returns the potentially annotated type that this type is a member of, if
+     * this type represents a nested type. For example, if this type is
+     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+     *
+     * <p>Returns {@code null} if this {@code AnnotatedType} represents a
+     *     top-level type, or a local or anonymous class, or a primitive type, or
+     *     void.
+     *
+     * <p>Returns {@code null} if this {@code AnnotatedType} is an instance of
+     *     {@code AnnotatedArrayType}, {@code AnnotatedTypeVariable}, or
+     *     {@code AnnotatedWildcardType}.
+     *
+     * @implSpec
+     * This default implementation returns {@code null} and performs no other
+     * action.
+     *
+     * @return an {@code AnnotatedType} object representing the potentially
+     *     annotated type that this type is a member of, or {@code null}
+     * @throws TypeNotPresentException if the owner type
+     *     refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if the owner type
+     *     refers to a parameterized type that cannot be instantiated
+     *     for any reason
+     *
+     * @since 1.9
+     */
+    default AnnotatedType getAnnotatedOwnerType() {
+        return null;
+    }
+
+    /**
      * Returns the underlying type that this annotated type represents.
      *
      * @return the type this annotated type represents
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedTypeVariable.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedTypeVariable.java	Tue Dec 22 13:41:12 2015 -0800
@@ -43,4 +43,19 @@
      * @see TypeVariable#getBounds()
      */
     AnnotatedType[] getAnnotatedBounds();
+
+    /**
+     * Returns the potentially annotated type that this type is a member of, if
+     * this type represents a nested type. For example, if this type is
+     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+     *
+     * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
+     *     of {@code AnnotatedTypeVariable}.
+     *
+     * @return {@code null}
+     *
+     * @since 1.9
+     */
+    @Override
+    AnnotatedType getAnnotatedOwnerType();
 }
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedWildcardType.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedWildcardType.java	Tue Dec 22 13:41:12 2015 -0800
@@ -54,4 +54,19 @@
      * @see WildcardType#getUpperBounds()
      */
     AnnotatedType[] getAnnotatedUpperBounds();
+
+    /**
+     * Returns the potentially annotated type that this type is a member of, if
+     * this type represents a nested type. For example, if this type is
+     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
+     *
+     * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
+     *     of {@code AnnotatedWildcardType}.
+     *
+     * @return {@code null}
+     *
+     * @since 1.9
+     */
+    @Override
+    AnnotatedType getAnnotatedOwnerType();
 }
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Tue Dec 22 13:41:12 2015 -0800
@@ -34,7 +34,6 @@
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BiFunction;
-import sun.misc.ProxyGenerator;
 import sun.misc.VM;
 import sun.reflect.CallerSensitive;
 import sun.reflect.Reflection;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,2031 @@
+/*
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import sun.security.action.GetBooleanAction;
+
+/**
+ * ProxyGenerator contains the code to generate a dynamic proxy class
+ * for the java.lang.reflect.Proxy API.
+ *
+ * The external interfaces to ProxyGenerator is the static
+ * "generateProxyClass" method.
+ *
+ * @author      Peter Jones
+ * @since       1.3
+ */
+class ProxyGenerator {
+    /*
+     * In the comments below, "JVMS" refers to The Java Virtual Machine
+     * Specification Second Edition and "JLS" refers to the original
+     * version of The Java Language Specification, unless otherwise
+     * specified.
+     */
+
+    /* generate 1.5-era class file version */
+    private static final int CLASSFILE_MAJOR_VERSION = 49;
+    private static final int CLASSFILE_MINOR_VERSION = 0;
+
+    /*
+     * beginning of constants copied from
+     * sun.tools.java.RuntimeConstants (which no longer exists):
+     */
+
+    /* constant pool tags */
+    private static final int CONSTANT_UTF8              = 1;
+    private static final int CONSTANT_UNICODE           = 2;
+    private static final int CONSTANT_INTEGER           = 3;
+    private static final int CONSTANT_FLOAT             = 4;
+    private static final int CONSTANT_LONG              = 5;
+    private static final int CONSTANT_DOUBLE            = 6;
+    private static final int CONSTANT_CLASS             = 7;
+    private static final int CONSTANT_STRING            = 8;
+    private static final int CONSTANT_FIELD             = 9;
+    private static final int CONSTANT_METHOD            = 10;
+    private static final int CONSTANT_INTERFACEMETHOD   = 11;
+    private static final int CONSTANT_NAMEANDTYPE       = 12;
+
+    /* access and modifier flags */
+    private static final int ACC_PUBLIC                 = 0x00000001;
+    private static final int ACC_PRIVATE                = 0x00000002;
+//  private static final int ACC_PROTECTED              = 0x00000004;
+    private static final int ACC_STATIC                 = 0x00000008;
+    private static final int ACC_FINAL                  = 0x00000010;
+//  private static final int ACC_SYNCHRONIZED           = 0x00000020;
+//  private static final int ACC_VOLATILE               = 0x00000040;
+//  private static final int ACC_TRANSIENT              = 0x00000080;
+//  private static final int ACC_NATIVE                 = 0x00000100;
+//  private static final int ACC_INTERFACE              = 0x00000200;
+//  private static final int ACC_ABSTRACT               = 0x00000400;
+    private static final int ACC_SUPER                  = 0x00000020;
+//  private static final int ACC_STRICT                 = 0x00000800;
+
+    /* opcodes */
+//  private static final int opc_nop                    = 0;
+    private static final int opc_aconst_null            = 1;
+//  private static final int opc_iconst_m1              = 2;
+    private static final int opc_iconst_0               = 3;
+//  private static final int opc_iconst_1               = 4;
+//  private static final int opc_iconst_2               = 5;
+//  private static final int opc_iconst_3               = 6;
+//  private static final int opc_iconst_4               = 7;
+//  private static final int opc_iconst_5               = 8;
+//  private static final int opc_lconst_0               = 9;
+//  private static final int opc_lconst_1               = 10;
+//  private static final int opc_fconst_0               = 11;
+//  private static final int opc_fconst_1               = 12;
+//  private static final int opc_fconst_2               = 13;
+//  private static final int opc_dconst_0               = 14;
+//  private static final int opc_dconst_1               = 15;
+    private static final int opc_bipush                 = 16;
+    private static final int opc_sipush                 = 17;
+    private static final int opc_ldc                    = 18;
+    private static final int opc_ldc_w                  = 19;
+//  private static final int opc_ldc2_w                 = 20;
+    private static final int opc_iload                  = 21;
+    private static final int opc_lload                  = 22;
+    private static final int opc_fload                  = 23;
+    private static final int opc_dload                  = 24;
+    private static final int opc_aload                  = 25;
+    private static final int opc_iload_0                = 26;
+//  private static final int opc_iload_1                = 27;
+//  private static final int opc_iload_2                = 28;
+//  private static final int opc_iload_3                = 29;
+    private static final int opc_lload_0                = 30;
+//  private static final int opc_lload_1                = 31;
+//  private static final int opc_lload_2                = 32;
+//  private static final int opc_lload_3                = 33;
+    private static final int opc_fload_0                = 34;
+//  private static final int opc_fload_1                = 35;
+//  private static final int opc_fload_2                = 36;
+//  private static final int opc_fload_3                = 37;
+    private static final int opc_dload_0                = 38;
+//  private static final int opc_dload_1                = 39;
+//  private static final int opc_dload_2                = 40;
+//  private static final int opc_dload_3                = 41;
+    private static final int opc_aload_0                = 42;
+//  private static final int opc_aload_1                = 43;
+//  private static final int opc_aload_2                = 44;
+//  private static final int opc_aload_3                = 45;
+//  private static final int opc_iaload                 = 46;
+//  private static final int opc_laload                 = 47;
+//  private static final int opc_faload                 = 48;
+//  private static final int opc_daload                 = 49;
+//  private static final int opc_aaload                 = 50;
+//  private static final int opc_baload                 = 51;
+//  private static final int opc_caload                 = 52;
+//  private static final int opc_saload                 = 53;
+//  private static final int opc_istore                 = 54;
+//  private static final int opc_lstore                 = 55;
+//  private static final int opc_fstore                 = 56;
+//  private static final int opc_dstore                 = 57;
+    private static final int opc_astore                 = 58;
+//  private static final int opc_istore_0               = 59;
+//  private static final int opc_istore_1               = 60;
+//  private static final int opc_istore_2               = 61;
+//  private static final int opc_istore_3               = 62;
+//  private static final int opc_lstore_0               = 63;
+//  private static final int opc_lstore_1               = 64;
+//  private static final int opc_lstore_2               = 65;
+//  private static final int opc_lstore_3               = 66;
+//  private static final int opc_fstore_0               = 67;
+//  private static final int opc_fstore_1               = 68;
+//  private static final int opc_fstore_2               = 69;
+//  private static final int opc_fstore_3               = 70;
+//  private static final int opc_dstore_0               = 71;
+//  private static final int opc_dstore_1               = 72;
+//  private static final int opc_dstore_2               = 73;
+//  private static final int opc_dstore_3               = 74;
+    private static final int opc_astore_0               = 75;
+//  private static final int opc_astore_1               = 76;
+//  private static final int opc_astore_2               = 77;
+//  private static final int opc_astore_3               = 78;
+//  private static final int opc_iastore                = 79;
+//  private static final int opc_lastore                = 80;
+//  private static final int opc_fastore                = 81;
+//  private static final int opc_dastore                = 82;
+    private static final int opc_aastore                = 83;
+//  private static final int opc_bastore                = 84;
+//  private static final int opc_castore                = 85;
+//  private static final int opc_sastore                = 86;
+    private static final int opc_pop                    = 87;
+//  private static final int opc_pop2                   = 88;
+    private static final int opc_dup                    = 89;
+//  private static final int opc_dup_x1                 = 90;
+//  private static final int opc_dup_x2                 = 91;
+//  private static final int opc_dup2                   = 92;
+//  private static final int opc_dup2_x1                = 93;
+//  private static final int opc_dup2_x2                = 94;
+//  private static final int opc_swap                   = 95;
+//  private static final int opc_iadd                   = 96;
+//  private static final int opc_ladd                   = 97;
+//  private static final int opc_fadd                   = 98;
+//  private static final int opc_dadd                   = 99;
+//  private static final int opc_isub                   = 100;
+//  private static final int opc_lsub                   = 101;
+//  private static final int opc_fsub                   = 102;
+//  private static final int opc_dsub                   = 103;
+//  private static final int opc_imul                   = 104;
+//  private static final int opc_lmul                   = 105;
+//  private static final int opc_fmul                   = 106;
+//  private static final int opc_dmul                   = 107;
+//  private static final int opc_idiv                   = 108;
+//  private static final int opc_ldiv                   = 109;
+//  private static final int opc_fdiv                   = 110;
+//  private static final int opc_ddiv                   = 111;
+//  private static final int opc_irem                   = 112;
+//  private static final int opc_lrem                   = 113;
+//  private static final int opc_frem                   = 114;
+//  private static final int opc_drem                   = 115;
+//  private static final int opc_ineg                   = 116;
+//  private static final int opc_lneg                   = 117;
+//  private static final int opc_fneg                   = 118;
+//  private static final int opc_dneg                   = 119;
+//  private static final int opc_ishl                   = 120;
+//  private static final int opc_lshl                   = 121;
+//  private static final int opc_ishr                   = 122;
+//  private static final int opc_lshr                   = 123;
+//  private static final int opc_iushr                  = 124;
+//  private static final int opc_lushr                  = 125;
+//  private static final int opc_iand                   = 126;
+//  private static final int opc_land                   = 127;
+//  private static final int opc_ior                    = 128;
+//  private static final int opc_lor                    = 129;
+//  private static final int opc_ixor                   = 130;
+//  private static final int opc_lxor                   = 131;
+//  private static final int opc_iinc                   = 132;
+//  private static final int opc_i2l                    = 133;
+//  private static final int opc_i2f                    = 134;
+//  private static final int opc_i2d                    = 135;
+//  private static final int opc_l2i                    = 136;
+//  private static final int opc_l2f                    = 137;
+//  private static final int opc_l2d                    = 138;
+//  private static final int opc_f2i                    = 139;
+//  private static final int opc_f2l                    = 140;
+//  private static final int opc_f2d                    = 141;
+//  private static final int opc_d2i                    = 142;
+//  private static final int opc_d2l                    = 143;
+//  private static final int opc_d2f                    = 144;
+//  private static final int opc_i2b                    = 145;
+//  private static final int opc_i2c                    = 146;
+//  private static final int opc_i2s                    = 147;
+//  private static final int opc_lcmp                   = 148;
+//  private static final int opc_fcmpl                  = 149;
+//  private static final int opc_fcmpg                  = 150;
+//  private static final int opc_dcmpl                  = 151;
+//  private static final int opc_dcmpg                  = 152;
+//  private static final int opc_ifeq                   = 153;
+//  private static final int opc_ifne                   = 154;
+//  private static final int opc_iflt                   = 155;
+//  private static final int opc_ifge                   = 156;
+//  private static final int opc_ifgt                   = 157;
+//  private static final int opc_ifle                   = 158;
+//  private static final int opc_if_icmpeq              = 159;
+//  private static final int opc_if_icmpne              = 160;
+//  private static final int opc_if_icmplt              = 161;
+//  private static final int opc_if_icmpge              = 162;
+//  private static final int opc_if_icmpgt              = 163;
+//  private static final int opc_if_icmple              = 164;
+//  private static final int opc_if_acmpeq              = 165;
+//  private static final int opc_if_acmpne              = 166;
+//  private static final int opc_goto                   = 167;
+//  private static final int opc_jsr                    = 168;
+//  private static final int opc_ret                    = 169;
+//  private static final int opc_tableswitch            = 170;
+//  private static final int opc_lookupswitch           = 171;
+    private static final int opc_ireturn                = 172;
+    private static final int opc_lreturn                = 173;
+    private static final int opc_freturn                = 174;
+    private static final int opc_dreturn                = 175;
+    private static final int opc_areturn                = 176;
+    private static final int opc_return                 = 177;
+    private static final int opc_getstatic              = 178;
+    private static final int opc_putstatic              = 179;
+    private static final int opc_getfield               = 180;
+//  private static final int opc_putfield               = 181;
+    private static final int opc_invokevirtual          = 182;
+    private static final int opc_invokespecial          = 183;
+    private static final int opc_invokestatic           = 184;
+    private static final int opc_invokeinterface        = 185;
+    private static final int opc_new                    = 187;
+//  private static final int opc_newarray               = 188;
+    private static final int opc_anewarray              = 189;
+//  private static final int opc_arraylength            = 190;
+    private static final int opc_athrow                 = 191;
+    private static final int opc_checkcast              = 192;
+//  private static final int opc_instanceof             = 193;
+//  private static final int opc_monitorenter           = 194;
+//  private static final int opc_monitorexit            = 195;
+    private static final int opc_wide                   = 196;
+//  private static final int opc_multianewarray         = 197;
+//  private static final int opc_ifnull                 = 198;
+//  private static final int opc_ifnonnull              = 199;
+//  private static final int opc_goto_w                 = 200;
+//  private static final int opc_jsr_w                  = 201;
+
+    // end of constants copied from sun.tools.java.RuntimeConstants
+
+    /** name of the superclass of proxy classes */
+    private static final String superclassName = "java/lang/reflect/Proxy";
+
+    /** name of field for storing a proxy instance's invocation handler */
+    private static final String handlerFieldName = "h";
+
+    /** debugging flag for saving generated class files */
+    private static final boolean saveGeneratedFiles =
+        java.security.AccessController.doPrivileged(
+            new GetBooleanAction(
+                "jdk.proxy.ProxyGenerator.saveGeneratedFiles")).booleanValue();
+
+    /**
+     * Generate a public proxy class given a name and a list of proxy interfaces.
+     */
+    static byte[] generateProxyClass(final String name,
+                                     Class<?>[] interfaces) {
+        return generateProxyClass(name, interfaces, (ACC_PUBLIC | ACC_FINAL | ACC_SUPER));
+    }
+
+    /**
+     * Generate a proxy class given a name and a list of proxy interfaces.
+     *
+     * @param name        the class name of the proxy class
+     * @param interfaces  proxy interfaces
+     * @param accessFlags access flags of the proxy class
+    */
+    static byte[] generateProxyClass(final String name,
+                                     Class<?>[] interfaces,
+                                     int accessFlags)
+    {
+        ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
+        final byte[] classFile = gen.generateClassFile();
+
+        if (saveGeneratedFiles) {
+            java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    try {
+                        int i = name.lastIndexOf('.');
+                        Path path;
+                        if (i > 0) {
+                            Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar));
+                            Files.createDirectories(dir);
+                            path = dir.resolve(name.substring(i+1, name.length()) + ".class");
+                        } else {
+                            path = Paths.get(name + ".class");
+                        }
+                        Files.write(path, classFile);
+                        return null;
+                    } catch (IOException e) {
+                        throw new InternalError(
+                            "I/O exception saving generated file: " + e);
+                    }
+                }
+            });
+        }
+
+        return classFile;
+    }
+
+    /* preloaded Method objects for methods in java.lang.Object */
+    private static Method hashCodeMethod;
+    private static Method equalsMethod;
+    private static Method toStringMethod;
+    static {
+        try {
+            hashCodeMethod = Object.class.getMethod("hashCode");
+            equalsMethod =
+                Object.class.getMethod("equals", new Class<?>[] { Object.class });
+            toStringMethod = Object.class.getMethod("toString");
+        } catch (NoSuchMethodException e) {
+            throw new NoSuchMethodError(e.getMessage());
+        }
+    }
+
+    /** name of proxy class */
+    private String className;
+
+    /** proxy interfaces */
+    private Class<?>[] interfaces;
+
+    /** proxy class access flags */
+    private int accessFlags;
+
+    /** constant pool of class being generated */
+    private ConstantPool cp = new ConstantPool();
+
+    /** FieldInfo struct for each field of generated class */
+    private List<FieldInfo> fields = new ArrayList<>();
+
+    /** MethodInfo struct for each method of generated class */
+    private List<MethodInfo> methods = new ArrayList<>();
+
+    /**
+     * maps method signature string to list of ProxyMethod objects for
+     * proxy methods with that signature
+     */
+    private Map<String, List<ProxyMethod>> proxyMethods = new HashMap<>();
+
+    /** count of ProxyMethod objects added to proxyMethods */
+    private int proxyMethodCount = 0;
+
+    /**
+     * Construct a ProxyGenerator to generate a proxy class with the
+     * specified name and for the given interfaces.
+     *
+     * A ProxyGenerator object contains the state for the ongoing
+     * generation of a particular proxy class.
+     */
+    private ProxyGenerator(String className, Class<?>[] interfaces, int accessFlags) {
+        this.className = className;
+        this.interfaces = interfaces;
+        this.accessFlags = accessFlags;
+    }
+
+    /**
+     * Generate a class file for the proxy class.  This method drives the
+     * class file generation process.
+     */
+    private byte[] generateClassFile() {
+
+        /* ============================================================
+         * Step 1: Assemble ProxyMethod objects for all methods to
+         * generate proxy dispatching code for.
+         */
+
+        /*
+         * Record that proxy methods are needed for the hashCode, equals,
+         * and toString methods of java.lang.Object.  This is done before
+         * the methods from the proxy interfaces so that the methods from
+         * java.lang.Object take precedence over duplicate methods in the
+         * proxy interfaces.
+         */
+        addProxyMethod(hashCodeMethod, Object.class);
+        addProxyMethod(equalsMethod, Object.class);
+        addProxyMethod(toStringMethod, Object.class);
+
+        /*
+         * Now record all of the methods from the proxy interfaces, giving
+         * earlier interfaces precedence over later ones with duplicate
+         * methods.
+         */
+        for (Class<?> intf : interfaces) {
+            for (Method m : intf.getMethods()) {
+                addProxyMethod(m, intf);
+            }
+        }
+
+        /*
+         * For each set of proxy methods with the same signature,
+         * verify that the methods' return types are compatible.
+         */
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            checkReturnTypes(sigmethods);
+        }
+
+        /* ============================================================
+         * Step 2: Assemble FieldInfo and MethodInfo structs for all of
+         * fields and methods in the class we are generating.
+         */
+        try {
+            methods.add(generateConstructor());
+
+            for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+                for (ProxyMethod pm : sigmethods) {
+
+                    // add static field for method's Method object
+                    fields.add(new FieldInfo(pm.methodFieldName,
+                        "Ljava/lang/reflect/Method;",
+                         ACC_PRIVATE | ACC_STATIC));
+
+                    // generate code for proxy method and add it
+                    methods.add(pm.generateMethod());
+                }
+            }
+
+            methods.add(generateStaticInitializer());
+
+        } catch (IOException e) {
+            throw new InternalError("unexpected I/O Exception", e);
+        }
+
+        if (methods.size() > 65535) {
+            throw new IllegalArgumentException("method limit exceeded");
+        }
+        if (fields.size() > 65535) {
+            throw new IllegalArgumentException("field limit exceeded");
+        }
+
+        /* ============================================================
+         * Step 3: Write the final class file.
+         */
+
+        /*
+         * Make sure that constant pool indexes are reserved for the
+         * following items before starting to write the final class file.
+         */
+        cp.getClass(dotToSlash(className));
+        cp.getClass(superclassName);
+        for (Class<?> intf: interfaces) {
+            cp.getClass(dotToSlash(intf.getName()));
+        }
+
+        /*
+         * Disallow new constant pool additions beyond this point, since
+         * we are about to write the final constant pool table.
+         */
+        cp.setReadOnly();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream(bout);
+
+        try {
+            /*
+             * Write all the items of the "ClassFile" structure.
+             * See JVMS section 4.1.
+             */
+                                        // u4 magic;
+            dout.writeInt(0xCAFEBABE);
+                                        // u2 minor_version;
+            dout.writeShort(CLASSFILE_MINOR_VERSION);
+                                        // u2 major_version;
+            dout.writeShort(CLASSFILE_MAJOR_VERSION);
+
+            cp.write(dout);             // (write constant pool)
+
+                                        // u2 access_flags;
+            dout.writeShort(accessFlags);
+                                        // u2 this_class;
+            dout.writeShort(cp.getClass(dotToSlash(className)));
+                                        // u2 super_class;
+            dout.writeShort(cp.getClass(superclassName));
+
+                                        // u2 interfaces_count;
+            dout.writeShort(interfaces.length);
+                                        // u2 interfaces[interfaces_count];
+            for (Class<?> intf : interfaces) {
+                dout.writeShort(cp.getClass(
+                    dotToSlash(intf.getName())));
+            }
+
+                                        // u2 fields_count;
+            dout.writeShort(fields.size());
+                                        // field_info fields[fields_count];
+            for (FieldInfo f : fields) {
+                f.write(dout);
+            }
+
+                                        // u2 methods_count;
+            dout.writeShort(methods.size());
+                                        // method_info methods[methods_count];
+            for (MethodInfo m : methods) {
+                m.write(dout);
+            }
+
+                                         // u2 attributes_count;
+            dout.writeShort(0); // (no ClassFile attributes for proxy classes)
+
+        } catch (IOException e) {
+            throw new InternalError("unexpected I/O Exception", e);
+        }
+
+        return bout.toByteArray();
+    }
+
+    /**
+     * Add another method to be proxied, either by creating a new
+     * ProxyMethod object or augmenting an old one for a duplicate
+     * method.
+     *
+     * "fromClass" indicates the proxy interface that the method was
+     * found through, which may be different from (a subinterface of)
+     * the method's "declaring class".  Note that the first Method
+     * object passed for a given name and descriptor identifies the
+     * Method object (and thus the declaring class) that will be
+     * passed to the invocation handler's "invoke" method for a given
+     * set of duplicate methods.
+     */
+    private void addProxyMethod(Method m, Class<?> fromClass) {
+        String name = m.getName();
+        Class<?>[] parameterTypes = m.getParameterTypes();
+        Class<?> returnType = m.getReturnType();
+        Class<?>[] exceptionTypes = m.getExceptionTypes();
+
+        String sig = name + getParameterDescriptors(parameterTypes);
+        List<ProxyMethod> sigmethods = proxyMethods.get(sig);
+        if (sigmethods != null) {
+            for (ProxyMethod pm : sigmethods) {
+                if (returnType == pm.returnType) {
+                    /*
+                     * Found a match: reduce exception types to the
+                     * greatest set of exceptions that can thrown
+                     * compatibly with the throws clauses of both
+                     * overridden methods.
+                     */
+                    List<Class<?>> legalExceptions = new ArrayList<>();
+                    collectCompatibleTypes(
+                        exceptionTypes, pm.exceptionTypes, legalExceptions);
+                    collectCompatibleTypes(
+                        pm.exceptionTypes, exceptionTypes, legalExceptions);
+                    pm.exceptionTypes = new Class<?>[legalExceptions.size()];
+                    pm.exceptionTypes =
+                        legalExceptions.toArray(pm.exceptionTypes);
+                    return;
+                }
+            }
+        } else {
+            sigmethods = new ArrayList<>(3);
+            proxyMethods.put(sig, sigmethods);
+        }
+        sigmethods.add(new ProxyMethod(name, parameterTypes, returnType,
+                                       exceptionTypes, fromClass));
+    }
+
+    /**
+     * For a given set of proxy methods with the same signature, check
+     * that their return types are compatible according to the Proxy
+     * specification.
+     *
+     * Specifically, if there is more than one such method, then all
+     * of the return types must be reference types, and there must be
+     * one return type that is assignable to each of the rest of them.
+     */
+    private static void checkReturnTypes(List<ProxyMethod> methods) {
+        /*
+         * If there is only one method with a given signature, there
+         * cannot be a conflict.  This is the only case in which a
+         * primitive (or void) return type is allowed.
+         */
+        if (methods.size() < 2) {
+            return;
+        }
+
+        /*
+         * List of return types that are not yet known to be
+         * assignable from ("covered" by) any of the others.
+         */
+        LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<>();
+
+    nextNewReturnType:
+        for (ProxyMethod pm : methods) {
+            Class<?> newReturnType = pm.returnType;
+            if (newReturnType.isPrimitive()) {
+                throw new IllegalArgumentException(
+                    "methods with same signature " +
+                    getFriendlyMethodSignature(pm.methodName,
+                                               pm.parameterTypes) +
+                    " but incompatible return types: " +
+                    newReturnType.getName() + " and others");
+            }
+            boolean added = false;
+
+            /*
+             * Compare the new return type to the existing uncovered
+             * return types.
+             */
+            ListIterator<Class<?>> liter = uncoveredReturnTypes.listIterator();
+            while (liter.hasNext()) {
+                Class<?> uncoveredReturnType = liter.next();
+
+                /*
+                 * If an existing uncovered return type is assignable
+                 * to this new one, then we can forget the new one.
+                 */
+                if (newReturnType.isAssignableFrom(uncoveredReturnType)) {
+                    assert !added;
+                    continue nextNewReturnType;
+                }
+
+                /*
+                 * If the new return type is assignable to an existing
+                 * uncovered one, then should replace the existing one
+                 * with the new one (or just forget the existing one,
+                 * if the new one has already be put in the list).
+                 */
+                if (uncoveredReturnType.isAssignableFrom(newReturnType)) {
+                    // (we can assume that each return type is unique)
+                    if (!added) {
+                        liter.set(newReturnType);
+                        added = true;
+                    } else {
+                        liter.remove();
+                    }
+                }
+            }
+
+            /*
+             * If we got through the list of existing uncovered return
+             * types without an assignability relationship, then add
+             * the new return type to the list of uncovered ones.
+             */
+            if (!added) {
+                uncoveredReturnTypes.add(newReturnType);
+            }
+        }
+
+        /*
+         * We shouldn't end up with more than one return type that is
+         * not assignable from any of the others.
+         */
+        if (uncoveredReturnTypes.size() > 1) {
+            ProxyMethod pm = methods.get(0);
+            throw new IllegalArgumentException(
+                "methods with same signature " +
+                getFriendlyMethodSignature(pm.methodName, pm.parameterTypes) +
+                " but incompatible return types: " + uncoveredReturnTypes);
+        }
+    }
+
+    /**
+     * A FieldInfo object contains information about a particular field
+     * in the class being generated.  The class mirrors the data items of
+     * the "field_info" structure of the class file format (see JVMS 4.5).
+     */
+    private class FieldInfo {
+        public int accessFlags;
+        public String name;
+        public String descriptor;
+
+        public FieldInfo(String name, String descriptor, int accessFlags) {
+            this.name = name;
+            this.descriptor = descriptor;
+            this.accessFlags = accessFlags;
+
+            /*
+             * Make sure that constant pool indexes are reserved for the
+             * following items before starting to write the final class file.
+             */
+            cp.getUtf8(name);
+            cp.getUtf8(descriptor);
+        }
+
+        public void write(DataOutputStream out) throws IOException {
+            /*
+             * Write all the items of the "field_info" structure.
+             * See JVMS section 4.5.
+             */
+                                        // u2 access_flags;
+            out.writeShort(accessFlags);
+                                        // u2 name_index;
+            out.writeShort(cp.getUtf8(name));
+                                        // u2 descriptor_index;
+            out.writeShort(cp.getUtf8(descriptor));
+                                        // u2 attributes_count;
+            out.writeShort(0);  // (no field_info attributes for proxy classes)
+        }
+    }
+
+    /**
+     * An ExceptionTableEntry object holds values for the data items of
+     * an entry in the "exception_table" item of the "Code" attribute of
+     * "method_info" structures (see JVMS 4.7.3).
+     */
+    private static class ExceptionTableEntry {
+        public short startPc;
+        public short endPc;
+        public short handlerPc;
+        public short catchType;
+
+        public ExceptionTableEntry(short startPc, short endPc,
+                                   short handlerPc, short catchType)
+        {
+            this.startPc = startPc;
+            this.endPc = endPc;
+            this.handlerPc = handlerPc;
+            this.catchType = catchType;
+        }
+    };
+
+    /**
+     * A MethodInfo object contains information about a particular method
+     * in the class being generated.  This class mirrors the data items of
+     * the "method_info" structure of the class file format (see JVMS 4.6).
+     */
+    private class MethodInfo {
+        public int accessFlags;
+        public String name;
+        public String descriptor;
+        public short maxStack;
+        public short maxLocals;
+        public ByteArrayOutputStream code = new ByteArrayOutputStream();
+        public List<ExceptionTableEntry> exceptionTable =
+            new ArrayList<ExceptionTableEntry>();
+        public short[] declaredExceptions;
+
+        public MethodInfo(String name, String descriptor, int accessFlags) {
+            this.name = name;
+            this.descriptor = descriptor;
+            this.accessFlags = accessFlags;
+
+            /*
+             * Make sure that constant pool indexes are reserved for the
+             * following items before starting to write the final class file.
+             */
+            cp.getUtf8(name);
+            cp.getUtf8(descriptor);
+            cp.getUtf8("Code");
+            cp.getUtf8("Exceptions");
+        }
+
+        public void write(DataOutputStream out) throws IOException {
+            /*
+             * Write all the items of the "method_info" structure.
+             * See JVMS section 4.6.
+             */
+                                        // u2 access_flags;
+            out.writeShort(accessFlags);
+                                        // u2 name_index;
+            out.writeShort(cp.getUtf8(name));
+                                        // u2 descriptor_index;
+            out.writeShort(cp.getUtf8(descriptor));
+                                        // u2 attributes_count;
+            out.writeShort(2);  // (two method_info attributes:)
+
+            // Write "Code" attribute. See JVMS section 4.7.3.
+
+                                        // u2 attribute_name_index;
+            out.writeShort(cp.getUtf8("Code"));
+                                        // u4 attribute_length;
+            out.writeInt(12 + code.size() + 8 * exceptionTable.size());
+                                        // u2 max_stack;
+            out.writeShort(maxStack);
+                                        // u2 max_locals;
+            out.writeShort(maxLocals);
+                                        // u2 code_length;
+            out.writeInt(code.size());
+                                        // u1 code[code_length];
+            code.writeTo(out);
+                                        // u2 exception_table_length;
+            out.writeShort(exceptionTable.size());
+            for (ExceptionTableEntry e : exceptionTable) {
+                                        // u2 start_pc;
+                out.writeShort(e.startPc);
+                                        // u2 end_pc;
+                out.writeShort(e.endPc);
+                                        // u2 handler_pc;
+                out.writeShort(e.handlerPc);
+                                        // u2 catch_type;
+                out.writeShort(e.catchType);
+            }
+                                        // u2 attributes_count;
+            out.writeShort(0);
+
+            // write "Exceptions" attribute.  See JVMS section 4.7.4.
+
+                                        // u2 attribute_name_index;
+            out.writeShort(cp.getUtf8("Exceptions"));
+                                        // u4 attributes_length;
+            out.writeInt(2 + 2 * declaredExceptions.length);
+                                        // u2 number_of_exceptions;
+            out.writeShort(declaredExceptions.length);
+                        // u2 exception_index_table[number_of_exceptions];
+            for (short value : declaredExceptions) {
+                out.writeShort(value);
+            }
+        }
+
+    }
+
+    /**
+     * A ProxyMethod object represents a proxy method in the proxy class
+     * being generated: a method whose implementation will encode and
+     * dispatch invocations to the proxy instance's invocation handler.
+     */
+    private class ProxyMethod {
+
+        public String methodName;
+        public Class<?>[] parameterTypes;
+        public Class<?> returnType;
+        public Class<?>[] exceptionTypes;
+        public Class<?> fromClass;
+        public String methodFieldName;
+
+        private ProxyMethod(String methodName, Class<?>[] parameterTypes,
+                            Class<?> returnType, Class<?>[] exceptionTypes,
+                            Class<?> fromClass)
+        {
+            this.methodName = methodName;
+            this.parameterTypes = parameterTypes;
+            this.returnType = returnType;
+            this.exceptionTypes = exceptionTypes;
+            this.fromClass = fromClass;
+            this.methodFieldName = "m" + proxyMethodCount++;
+        }
+
+        /**
+         * Return a MethodInfo object for this method, including generating
+         * the code and exception table entry.
+         */
+        private MethodInfo generateMethod() throws IOException {
+            String desc = getMethodDescriptor(parameterTypes, returnType);
+            MethodInfo minfo = new MethodInfo(methodName, desc,
+                ACC_PUBLIC | ACC_FINAL);
+
+            int[] parameterSlot = new int[parameterTypes.length];
+            int nextSlot = 1;
+            for (int i = 0; i < parameterSlot.length; i++) {
+                parameterSlot[i] = nextSlot;
+                nextSlot += getWordsPerType(parameterTypes[i]);
+            }
+            int localSlot0 = nextSlot;
+            short pc, tryBegin = 0, tryEnd;
+
+            DataOutputStream out = new DataOutputStream(minfo.code);
+
+            code_aload(0, out);
+
+            out.writeByte(opc_getfield);
+            out.writeShort(cp.getFieldRef(
+                superclassName,
+                handlerFieldName, "Ljava/lang/reflect/InvocationHandler;"));
+
+            code_aload(0, out);
+
+            out.writeByte(opc_getstatic);
+            out.writeShort(cp.getFieldRef(
+                dotToSlash(className),
+                methodFieldName, "Ljava/lang/reflect/Method;"));
+
+            if (parameterTypes.length > 0) {
+
+                code_ipush(parameterTypes.length, out);
+
+                out.writeByte(opc_anewarray);
+                out.writeShort(cp.getClass("java/lang/Object"));
+
+                for (int i = 0; i < parameterTypes.length; i++) {
+
+                    out.writeByte(opc_dup);
+
+                    code_ipush(i, out);
+
+                    codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
+
+                    out.writeByte(opc_aastore);
+                }
+            } else {
+
+                out.writeByte(opc_aconst_null);
+            }
+
+            out.writeByte(opc_invokeinterface);
+            out.writeShort(cp.getInterfaceMethodRef(
+                "java/lang/reflect/InvocationHandler",
+                "invoke",
+                "(Ljava/lang/Object;Ljava/lang/reflect/Method;" +
+                    "[Ljava/lang/Object;)Ljava/lang/Object;"));
+            out.writeByte(4);
+            out.writeByte(0);
+
+            if (returnType == void.class) {
+
+                out.writeByte(opc_pop);
+
+                out.writeByte(opc_return);
+
+            } else {
+
+                codeUnwrapReturnValue(returnType, out);
+            }
+
+            tryEnd = pc = (short) minfo.code.size();
+
+            List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
+            if (catchList.size() > 0) {
+
+                for (Class<?> ex : catchList) {
+                    minfo.exceptionTable.add(new ExceptionTableEntry(
+                        tryBegin, tryEnd, pc,
+                        cp.getClass(dotToSlash(ex.getName()))));
+                }
+
+                out.writeByte(opc_athrow);
+
+                pc = (short) minfo.code.size();
+
+                minfo.exceptionTable.add(new ExceptionTableEntry(
+                    tryBegin, tryEnd, pc, cp.getClass("java/lang/Throwable")));
+
+                code_astore(localSlot0, out);
+
+                out.writeByte(opc_new);
+                out.writeShort(cp.getClass(
+                    "java/lang/reflect/UndeclaredThrowableException"));
+
+                out.writeByte(opc_dup);
+
+                code_aload(localSlot0, out);
+
+                out.writeByte(opc_invokespecial);
+
+                out.writeShort(cp.getMethodRef(
+                    "java/lang/reflect/UndeclaredThrowableException",
+                    "<init>", "(Ljava/lang/Throwable;)V"));
+
+                out.writeByte(opc_athrow);
+            }
+
+            if (minfo.code.size() > 65535) {
+                throw new IllegalArgumentException("code size limit exceeded");
+            }
+
+            minfo.maxStack = 10;
+            minfo.maxLocals = (short) (localSlot0 + 1);
+            minfo.declaredExceptions = new short[exceptionTypes.length];
+            for (int i = 0; i < exceptionTypes.length; i++) {
+                minfo.declaredExceptions[i] = cp.getClass(
+                    dotToSlash(exceptionTypes[i].getName()));
+            }
+
+            return minfo;
+        }
+
+        /**
+         * Generate code for wrapping an argument of the given type
+         * whose value can be found at the specified local variable
+         * index, in order for it to be passed (as an Object) to the
+         * invocation handler's "invoke" method.  The code is written
+         * to the supplied stream.
+         */
+        private void codeWrapArgument(Class<?> type, int slot,
+                                      DataOutputStream out)
+            throws IOException
+        {
+            if (type.isPrimitive()) {
+                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
+
+                if (type == int.class ||
+                    type == boolean.class ||
+                    type == byte.class ||
+                    type == char.class ||
+                    type == short.class)
+                {
+                    code_iload(slot, out);
+                } else if (type == long.class) {
+                    code_lload(slot, out);
+                } else if (type == float.class) {
+                    code_fload(slot, out);
+                } else if (type == double.class) {
+                    code_dload(slot, out);
+                } else {
+                    throw new AssertionError();
+                }
+
+                out.writeByte(opc_invokestatic);
+                out.writeShort(cp.getMethodRef(
+                    prim.wrapperClassName,
+                    "valueOf", prim.wrapperValueOfDesc));
+
+            } else {
+
+                code_aload(slot, out);
+            }
+        }
+
+        /**
+         * Generate code for unwrapping a return value of the given
+         * type from the invocation handler's "invoke" method (as type
+         * Object) to its correct type.  The code is written to the
+         * supplied stream.
+         */
+        private void codeUnwrapReturnValue(Class<?> type, DataOutputStream out)
+            throws IOException
+        {
+            if (type.isPrimitive()) {
+                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
+
+                out.writeByte(opc_checkcast);
+                out.writeShort(cp.getClass(prim.wrapperClassName));
+
+                out.writeByte(opc_invokevirtual);
+                out.writeShort(cp.getMethodRef(
+                    prim.wrapperClassName,
+                    prim.unwrapMethodName, prim.unwrapMethodDesc));
+
+                if (type == int.class ||
+                    type == boolean.class ||
+                    type == byte.class ||
+                    type == char.class ||
+                    type == short.class)
+                {
+                    out.writeByte(opc_ireturn);
+                } else if (type == long.class) {
+                    out.writeByte(opc_lreturn);
+                } else if (type == float.class) {
+                    out.writeByte(opc_freturn);
+                } else if (type == double.class) {
+                    out.writeByte(opc_dreturn);
+                } else {
+                    throw new AssertionError();
+                }
+
+            } else {
+
+                out.writeByte(opc_checkcast);
+                out.writeShort(cp.getClass(dotToSlash(type.getName())));
+
+                out.writeByte(opc_areturn);
+            }
+        }
+
+        /**
+         * Generate code for initializing the static field that stores
+         * the Method object for this proxy method.  The code is written
+         * to the supplied stream.
+         */
+        private void codeFieldInitialization(DataOutputStream out)
+            throws IOException
+        {
+            codeClassForName(fromClass, out);
+
+            code_ldc(cp.getString(methodName), out);
+
+            code_ipush(parameterTypes.length, out);
+
+            out.writeByte(opc_anewarray);
+            out.writeShort(cp.getClass("java/lang/Class"));
+
+            for (int i = 0; i < parameterTypes.length; i++) {
+
+                out.writeByte(opc_dup);
+
+                code_ipush(i, out);
+
+                if (parameterTypes[i].isPrimitive()) {
+                    PrimitiveTypeInfo prim =
+                        PrimitiveTypeInfo.get(parameterTypes[i]);
+
+                    out.writeByte(opc_getstatic);
+                    out.writeShort(cp.getFieldRef(
+                        prim.wrapperClassName, "TYPE", "Ljava/lang/Class;"));
+
+                } else {
+                    codeClassForName(parameterTypes[i], out);
+                }
+
+                out.writeByte(opc_aastore);
+            }
+
+            out.writeByte(opc_invokevirtual);
+            out.writeShort(cp.getMethodRef(
+                "java/lang/Class",
+                "getMethod",
+                "(Ljava/lang/String;[Ljava/lang/Class;)" +
+                "Ljava/lang/reflect/Method;"));
+
+            out.writeByte(opc_putstatic);
+            out.writeShort(cp.getFieldRef(
+                dotToSlash(className),
+                methodFieldName, "Ljava/lang/reflect/Method;"));
+        }
+    }
+
+    /**
+     * Generate the constructor method for the proxy class.
+     */
+    private MethodInfo generateConstructor() throws IOException {
+        MethodInfo minfo = new MethodInfo(
+            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V",
+            ACC_PUBLIC);
+
+        DataOutputStream out = new DataOutputStream(minfo.code);
+
+        code_aload(0, out);
+
+        code_aload(1, out);
+
+        out.writeByte(opc_invokespecial);
+        out.writeShort(cp.getMethodRef(
+            superclassName,
+            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V"));
+
+        out.writeByte(opc_return);
+
+        minfo.maxStack = 10;
+        minfo.maxLocals = 2;
+        minfo.declaredExceptions = new short[0];
+
+        return minfo;
+    }
+
+    /**
+     * Generate the static initializer method for the proxy class.
+     */
+    private MethodInfo generateStaticInitializer() throws IOException {
+        MethodInfo minfo = new MethodInfo(
+            "<clinit>", "()V", ACC_STATIC);
+
+        int localSlot0 = 1;
+        short pc, tryBegin = 0, tryEnd;
+
+        DataOutputStream out = new DataOutputStream(minfo.code);
+
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            for (ProxyMethod pm : sigmethods) {
+                pm.codeFieldInitialization(out);
+            }
+        }
+
+        out.writeByte(opc_return);
+
+        tryEnd = pc = (short) minfo.code.size();
+
+        minfo.exceptionTable.add(new ExceptionTableEntry(
+            tryBegin, tryEnd, pc,
+            cp.getClass("java/lang/NoSuchMethodException")));
+
+        code_astore(localSlot0, out);
+
+        out.writeByte(opc_new);
+        out.writeShort(cp.getClass("java/lang/NoSuchMethodError"));
+
+        out.writeByte(opc_dup);
+
+        code_aload(localSlot0, out);
+
+        out.writeByte(opc_invokevirtual);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
+
+        out.writeByte(opc_invokespecial);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/NoSuchMethodError", "<init>", "(Ljava/lang/String;)V"));
+
+        out.writeByte(opc_athrow);
+
+        pc = (short) minfo.code.size();
+
+        minfo.exceptionTable.add(new ExceptionTableEntry(
+            tryBegin, tryEnd, pc,
+            cp.getClass("java/lang/ClassNotFoundException")));
+
+        code_astore(localSlot0, out);
+
+        out.writeByte(opc_new);
+        out.writeShort(cp.getClass("java/lang/NoClassDefFoundError"));
+
+        out.writeByte(opc_dup);
+
+        code_aload(localSlot0, out);
+
+        out.writeByte(opc_invokevirtual);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
+
+        out.writeByte(opc_invokespecial);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/NoClassDefFoundError",
+            "<init>", "(Ljava/lang/String;)V"));
+
+        out.writeByte(opc_athrow);
+
+        if (minfo.code.size() > 65535) {
+            throw new IllegalArgumentException("code size limit exceeded");
+        }
+
+        minfo.maxStack = 10;
+        minfo.maxLocals = (short) (localSlot0 + 1);
+        minfo.declaredExceptions = new short[0];
+
+        return minfo;
+    }
+
+
+    /*
+     * =============== Code Generation Utility Methods ===============
+     */
+
+    /*
+     * The following methods generate code for the load or store operation
+     * indicated by their name for the given local variable.  The code is
+     * written to the supplied stream.
+     */
+
+    private void code_iload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_iload, opc_iload_0, out);
+    }
+
+    private void code_lload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_lload, opc_lload_0, out);
+    }
+
+    private void code_fload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_fload, opc_fload_0, out);
+    }
+
+    private void code_dload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_dload, opc_dload_0, out);
+    }
+
+    private void code_aload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_aload, opc_aload_0, out);
+    }
+
+//  private void code_istore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_istore, opc_istore_0, out);
+//  }
+
+//  private void code_lstore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_lstore, opc_lstore_0, out);
+//  }
+
+//  private void code_fstore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_fstore, opc_fstore_0, out);
+//  }
+
+//  private void code_dstore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_dstore, opc_dstore_0, out);
+//  }
+
+    private void code_astore(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_astore, opc_astore_0, out);
+    }
+
+    /**
+     * Generate code for a load or store instruction for the given local
+     * variable.  The code is written to the supplied stream.
+     *
+     * "opcode" indicates the opcode form of the desired load or store
+     * instruction that takes an explicit local variable index, and
+     * "opcode_0" indicates the corresponding form of the instruction
+     * with the implicit index 0.
+     */
+    private void codeLocalLoadStore(int lvar, int opcode, int opcode_0,
+                                    DataOutputStream out)
+        throws IOException
+    {
+        assert lvar >= 0 && lvar <= 0xFFFF;
+        if (lvar <= 3) {
+            out.writeByte(opcode_0 + lvar);
+        } else if (lvar <= 0xFF) {
+            out.writeByte(opcode);
+            out.writeByte(lvar & 0xFF);
+        } else {
+            /*
+             * Use the "wide" instruction modifier for local variable
+             * indexes that do not fit into an unsigned byte.
+             */
+            out.writeByte(opc_wide);
+            out.writeByte(opcode);
+            out.writeShort(lvar & 0xFFFF);
+        }
+    }
+
+    /**
+     * Generate code for an "ldc" instruction for the given constant pool
+     * index (the "ldc_w" instruction is used if the index does not fit
+     * into an unsigned byte).  The code is written to the supplied stream.
+     */
+    private void code_ldc(int index, DataOutputStream out)
+        throws IOException
+    {
+        assert index >= 0 && index <= 0xFFFF;
+        if (index <= 0xFF) {
+            out.writeByte(opc_ldc);
+            out.writeByte(index & 0xFF);
+        } else {
+            out.writeByte(opc_ldc_w);
+            out.writeShort(index & 0xFFFF);
+        }
+    }
+
+    /**
+     * Generate code to push a constant integer value on to the operand
+     * stack, using the "iconst_<i>", "bipush", or "sipush" instructions
+     * depending on the size of the value.  The code is written to the
+     * supplied stream.
+     */
+    private void code_ipush(int value, DataOutputStream out)
+        throws IOException
+    {
+        if (value >= -1 && value <= 5) {
+            out.writeByte(opc_iconst_0 + value);
+        } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+            out.writeByte(opc_bipush);
+            out.writeByte(value & 0xFF);
+        } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+            out.writeByte(opc_sipush);
+            out.writeShort(value & 0xFFFF);
+        } else {
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Generate code to invoke the Class.forName with the name of the given
+     * class to get its Class object at runtime.  The code is written to
+     * the supplied stream.  Note that the code generated by this method
+     * may caused the checked ClassNotFoundException to be thrown.
+     */
+    private void codeClassForName(Class<?> cl, DataOutputStream out)
+        throws IOException
+    {
+        code_ldc(cp.getString(cl.getName()), out);
+
+        out.writeByte(opc_invokestatic);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/Class",
+            "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
+    }
+
+
+    /*
+     * ==================== General Utility Methods ====================
+     */
+
+    /**
+     * Convert a fully qualified class name that uses '.' as the package
+     * separator, the external representation used by the Java language
+     * and APIs, to a fully qualified class name that uses '/' as the
+     * package separator, the representation used in the class file
+     * format (see JVMS section 4.2).
+     */
+    private static String dotToSlash(String name) {
+        return name.replace('.', '/');
+    }
+
+    /**
+     * Return the "method descriptor" string for a method with the given
+     * parameter types and return type.  See JVMS section 4.3.3.
+     */
+    private static String getMethodDescriptor(Class<?>[] parameterTypes,
+                                              Class<?> returnType)
+    {
+        return getParameterDescriptors(parameterTypes) +
+            ((returnType == void.class) ? "V" : getFieldType(returnType));
+    }
+
+    /**
+     * Return the list of "parameter descriptor" strings enclosed in
+     * parentheses corresponding to the given parameter types (in other
+     * words, a method descriptor without a return descriptor).  This
+     * string is useful for constructing string keys for methods without
+     * regard to their return type.
+     */
+    private static String getParameterDescriptors(Class<?>[] parameterTypes) {
+        StringBuilder desc = new StringBuilder("(");
+        for (int i = 0; i < parameterTypes.length; i++) {
+            desc.append(getFieldType(parameterTypes[i]));
+        }
+        desc.append(')');
+        return desc.toString();
+    }
+
+    /**
+     * Return the "field type" string for the given type, appropriate for
+     * a field descriptor, a parameter descriptor, or a return descriptor
+     * other than "void".  See JVMS section 4.3.2.
+     */
+    private static String getFieldType(Class<?> type) {
+        if (type.isPrimitive()) {
+            return PrimitiveTypeInfo.get(type).baseTypeString;
+        } else if (type.isArray()) {
+            /*
+             * According to JLS 20.3.2, the getName() method on Class does
+             * return the VM type descriptor format for array classes (only);
+             * using that should be quicker than the otherwise obvious code:
+             *
+             *     return "[" + getTypeDescriptor(type.getComponentType());
+             */
+            return type.getName().replace('.', '/');
+        } else {
+            return "L" + dotToSlash(type.getName()) + ";";
+        }
+    }
+
+    /**
+     * Returns a human-readable string representing the signature of a
+     * method with the given name and parameter types.
+     */
+    private static String getFriendlyMethodSignature(String name,
+                                                     Class<?>[] parameterTypes)
+    {
+        StringBuilder sig = new StringBuilder(name);
+        sig.append('(');
+        for (int i = 0; i < parameterTypes.length; i++) {
+            if (i > 0) {
+                sig.append(',');
+            }
+            Class<?> parameterType = parameterTypes[i];
+            int dimensions = 0;
+            while (parameterType.isArray()) {
+                parameterType = parameterType.getComponentType();
+                dimensions++;
+            }
+            sig.append(parameterType.getName());
+            while (dimensions-- > 0) {
+                sig.append("[]");
+            }
+        }
+        sig.append(')');
+        return sig.toString();
+    }
+
+    /**
+     * Return the number of abstract "words", or consecutive local variable
+     * indexes, required to contain a value of the given type.  See JVMS
+     * section 3.6.1.
+     *
+     * Note that the original version of the JVMS contained a definition of
+     * this abstract notion of a "word" in section 3.4, but that definition
+     * was removed for the second edition.
+     */
+    private static int getWordsPerType(Class<?> type) {
+        if (type == long.class || type == double.class) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+
+    /**
+     * Add to the given list all of the types in the "from" array that
+     * are not already contained in the list and are assignable to at
+     * least one of the types in the "with" array.
+     *
+     * This method is useful for computing the greatest common set of
+     * declared exceptions from duplicate methods inherited from
+     * different interfaces.
+     */
+    private static void collectCompatibleTypes(Class<?>[] from,
+                                               Class<?>[] with,
+                                               List<Class<?>> list)
+    {
+        for (Class<?> fc: from) {
+            if (!list.contains(fc)) {
+                for (Class<?> wc: with) {
+                    if (wc.isAssignableFrom(fc)) {
+                        list.add(fc);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Given the exceptions declared in the throws clause of a proxy method,
+     * compute the exceptions that need to be caught from the invocation
+     * handler's invoke method and rethrown intact in the method's
+     * implementation before catching other Throwables and wrapping them
+     * in UndeclaredThrowableExceptions.
+     *
+     * The exceptions to be caught are returned in a List object.  Each
+     * exception in the returned list is guaranteed to not be a subclass of
+     * any of the other exceptions in the list, so the catch blocks for
+     * these exceptions may be generated in any order relative to each other.
+     *
+     * Error and RuntimeException are each always contained by the returned
+     * list (if none of their superclasses are contained), since those
+     * unchecked exceptions should always be rethrown intact, and thus their
+     * subclasses will never appear in the returned list.
+     *
+     * The returned List will be empty if java.lang.Throwable is in the
+     * given list of declared exceptions, indicating that no exceptions
+     * need to be caught.
+     */
+    private static List<Class<?>> computeUniqueCatchList(Class<?>[] exceptions) {
+        List<Class<?>> uniqueList = new ArrayList<>();
+                                                // unique exceptions to catch
+
+        uniqueList.add(Error.class);            // always catch/rethrow these
+        uniqueList.add(RuntimeException.class);
+
+    nextException:
+        for (Class<?> ex: exceptions) {
+            if (ex.isAssignableFrom(Throwable.class)) {
+                /*
+                 * If Throwable is declared to be thrown by the proxy method,
+                 * then no catch blocks are necessary, because the invoke
+                 * can, at most, throw Throwable anyway.
+                 */
+                uniqueList.clear();
+                break;
+            } else if (!Throwable.class.isAssignableFrom(ex)) {
+                /*
+                 * Ignore types that cannot be thrown by the invoke method.
+                 */
+                continue;
+            }
+            /*
+             * Compare this exception against the current list of
+             * exceptions that need to be caught:
+             */
+            for (int j = 0; j < uniqueList.size();) {
+                Class<?> ex2 = uniqueList.get(j);
+                if (ex2.isAssignableFrom(ex)) {
+                    /*
+                     * if a superclass of this exception is already on
+                     * the list to catch, then ignore this one and continue;
+                     */
+                    continue nextException;
+                } else if (ex.isAssignableFrom(ex2)) {
+                    /*
+                     * if a subclass of this exception is on the list
+                     * to catch, then remove it;
+                     */
+                    uniqueList.remove(j);
+                } else {
+                    j++;        // else continue comparing.
+                }
+            }
+            // This exception is unique (so far): add it to the list to catch.
+            uniqueList.add(ex);
+        }
+        return uniqueList;
+    }
+
+    /**
+     * A PrimitiveTypeInfo object contains assorted information about
+     * a primitive type in its public fields.  The struct for a particular
+     * primitive type can be obtained using the static "get" method.
+     */
+    private static class PrimitiveTypeInfo {
+
+        /** "base type" used in various descriptors (see JVMS section 4.3.2) */
+        public String baseTypeString;
+
+        /** name of corresponding wrapper class */
+        public String wrapperClassName;
+
+        /** method descriptor for wrapper class "valueOf" factory method */
+        public String wrapperValueOfDesc;
+
+        /** name of wrapper class method for retrieving primitive value */
+        public String unwrapMethodName;
+
+        /** descriptor of same method */
+        public String unwrapMethodDesc;
+
+        private static Map<Class<?>,PrimitiveTypeInfo> table = new HashMap<>();
+        static {
+            add(byte.class, Byte.class);
+            add(char.class, Character.class);
+            add(double.class, Double.class);
+            add(float.class, Float.class);
+            add(int.class, Integer.class);
+            add(long.class, Long.class);
+            add(short.class, Short.class);
+            add(boolean.class, Boolean.class);
+        }
+
+        private static void add(Class<?> primitiveClass, Class<?> wrapperClass) {
+            table.put(primitiveClass,
+                      new PrimitiveTypeInfo(primitiveClass, wrapperClass));
+        }
+
+        private PrimitiveTypeInfo(Class<?> primitiveClass, Class<?> wrapperClass) {
+            assert primitiveClass.isPrimitive();
+
+            baseTypeString =
+                Array.newInstance(primitiveClass, 0)
+                .getClass().getName().substring(1);
+            wrapperClassName = dotToSlash(wrapperClass.getName());
+            wrapperValueOfDesc =
+                "(" + baseTypeString + ")L" + wrapperClassName + ";";
+            unwrapMethodName = primitiveClass.getName() + "Value";
+            unwrapMethodDesc = "()" + baseTypeString;
+        }
+
+        public static PrimitiveTypeInfo get(Class<?> cl) {
+            return table.get(cl);
+        }
+    }
+
+
+    /**
+     * A ConstantPool object represents the constant pool of a class file
+     * being generated.  This representation of a constant pool is designed
+     * specifically for use by ProxyGenerator; in particular, it assumes
+     * that constant pool entries will not need to be resorted (for example,
+     * by their type, as the Java compiler does), so that the final index
+     * value can be assigned and used when an entry is first created.
+     *
+     * Note that new entries cannot be created after the constant pool has
+     * been written to a class file.  To prevent such logic errors, a
+     * ConstantPool instance can be marked "read only", so that further
+     * attempts to add new entries will fail with a runtime exception.
+     *
+     * See JVMS section 4.4 for more information about the constant pool
+     * of a class file.
+     */
+    private static class ConstantPool {
+
+        /**
+         * list of constant pool entries, in constant pool index order.
+         *
+         * This list is used when writing the constant pool to a stream
+         * and for assigning the next index value.  Note that element 0
+         * of this list corresponds to constant pool index 1.
+         */
+        private List<Entry> pool = new ArrayList<>(32);
+
+        /**
+         * maps constant pool data of all types to constant pool indexes.
+         *
+         * This map is used to look up the index of an existing entry for
+         * values of all types.
+         */
+        private Map<Object,Short> map = new HashMap<>(16);
+
+        /** true if no new constant pool entries may be added */
+        private boolean readOnly = false;
+
+        /**
+         * Get or assign the index for a CONSTANT_Utf8 entry.
+         */
+        public short getUtf8(String s) {
+            if (s == null) {
+                throw new NullPointerException();
+            }
+            return getValue(s);
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_Integer entry.
+         */
+        public short getInteger(int i) {
+            return getValue(i);
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_Float entry.
+         */
+        public short getFloat(float f) {
+            return getValue(new Float(f));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_Class entry.
+         */
+        public short getClass(String name) {
+            short utf8Index = getUtf8(name);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_CLASS, utf8Index));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_String entry.
+         */
+        public short getString(String s) {
+            short utf8Index = getUtf8(s);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_STRING, utf8Index));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_FieldRef entry.
+         */
+        public short getFieldRef(String className,
+                                 String name, String descriptor)
+        {
+            short classIndex = getClass(className);
+            short nameAndTypeIndex = getNameAndType(name, descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_FIELD, classIndex, nameAndTypeIndex));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_MethodRef entry.
+         */
+        public short getMethodRef(String className,
+                                  String name, String descriptor)
+        {
+            short classIndex = getClass(className);
+            short nameAndTypeIndex = getNameAndType(name, descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_METHOD, classIndex, nameAndTypeIndex));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_InterfaceMethodRef entry.
+         */
+        public short getInterfaceMethodRef(String className, String name,
+                                           String descriptor)
+        {
+            short classIndex = getClass(className);
+            short nameAndTypeIndex = getNameAndType(name, descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_INTERFACEMETHOD, classIndex, nameAndTypeIndex));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_NameAndType entry.
+         */
+        public short getNameAndType(String name, String descriptor) {
+            short nameIndex = getUtf8(name);
+            short descriptorIndex = getUtf8(descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_NAMEANDTYPE, nameIndex, descriptorIndex));
+        }
+
+        /**
+         * Set this ConstantPool instance to be "read only".
+         *
+         * After this method has been called, further requests to get
+         * an index for a non-existent entry will cause an InternalError
+         * to be thrown instead of creating of the entry.
+         */
+        public void setReadOnly() {
+            readOnly = true;
+        }
+
+        /**
+         * Write this constant pool to a stream as part of
+         * the class file format.
+         *
+         * This consists of writing the "constant_pool_count" and
+         * "constant_pool[]" items of the "ClassFile" structure, as
+         * described in JVMS section 4.1.
+         */
+        public void write(OutputStream out) throws IOException {
+            DataOutputStream dataOut = new DataOutputStream(out);
+
+            // constant_pool_count: number of entries plus one
+            dataOut.writeShort(pool.size() + 1);
+
+            for (Entry e : pool) {
+                e.write(dataOut);
+            }
+        }
+
+        /**
+         * Add a new constant pool entry and return its index.
+         */
+        private short addEntry(Entry entry) {
+            pool.add(entry);
+            /*
+             * Note that this way of determining the index of the
+             * added entry is wrong if this pool supports
+             * CONSTANT_Long or CONSTANT_Double entries.
+             */
+            if (pool.size() >= 65535) {
+                throw new IllegalArgumentException(
+                    "constant pool size limit exceeded");
+            }
+            return (short) pool.size();
+        }
+
+        /**
+         * Get or assign the index for an entry of a type that contains
+         * a direct value.  The type of the given object determines the
+         * type of the desired entry as follows:
+         *
+         *      java.lang.String        CONSTANT_Utf8
+         *      java.lang.Integer       CONSTANT_Integer
+         *      java.lang.Float         CONSTANT_Float
+         *      java.lang.Long          CONSTANT_Long
+         *      java.lang.Double        CONSTANT_DOUBLE
+         */
+        private short getValue(Object key) {
+            Short index = map.get(key);
+            if (index != null) {
+                return index.shortValue();
+            } else {
+                if (readOnly) {
+                    throw new InternalError(
+                        "late constant pool addition: " + key);
+                }
+                short i = addEntry(new ValueEntry(key));
+                map.put(key, i);
+                return i;
+            }
+        }
+
+        /**
+         * Get or assign the index for an entry of a type that contains
+         * references to other constant pool entries.
+         */
+        private short getIndirect(IndirectEntry e) {
+            Short index = map.get(e);
+            if (index != null) {
+                return index.shortValue();
+            } else {
+                if (readOnly) {
+                    throw new InternalError("late constant pool addition");
+                }
+                short i = addEntry(e);
+                map.put(e, i);
+                return i;
+            }
+        }
+
+        /**
+         * Entry is the abstact superclass of all constant pool entry types
+         * that can be stored in the "pool" list; its purpose is to define a
+         * common method for writing constant pool entries to a class file.
+         */
+        private abstract static class Entry {
+            public abstract void write(DataOutputStream out)
+                throws IOException;
+        }
+
+        /**
+         * ValueEntry represents a constant pool entry of a type that
+         * contains a direct value (see the comments for the "getValue"
+         * method for a list of such types).
+         *
+         * ValueEntry objects are not used as keys for their entries in the
+         * Map "map", so no useful hashCode or equals methods are defined.
+         */
+        private static class ValueEntry extends Entry {
+            private Object value;
+
+            public ValueEntry(Object value) {
+                this.value = value;
+            }
+
+            public void write(DataOutputStream out) throws IOException {
+                if (value instanceof String) {
+                    out.writeByte(CONSTANT_UTF8);
+                    out.writeUTF((String) value);
+                } else if (value instanceof Integer) {
+                    out.writeByte(CONSTANT_INTEGER);
+                    out.writeInt(((Integer) value).intValue());
+                } else if (value instanceof Float) {
+                    out.writeByte(CONSTANT_FLOAT);
+                    out.writeFloat(((Float) value).floatValue());
+                } else if (value instanceof Long) {
+                    out.writeByte(CONSTANT_LONG);
+                    out.writeLong(((Long) value).longValue());
+                } else if (value instanceof Double) {
+                    out.writeDouble(CONSTANT_DOUBLE);
+                    out.writeDouble(((Double) value).doubleValue());
+                } else {
+                    throw new InternalError("bogus value entry: " + value);
+                }
+            }
+        }
+
+        /**
+         * IndirectEntry represents a constant pool entry of a type that
+         * references other constant pool entries, i.e., the following types:
+         *
+         *      CONSTANT_Class, CONSTANT_String, CONSTANT_Fieldref,
+         *      CONSTANT_Methodref, CONSTANT_InterfaceMethodref, and
+         *      CONSTANT_NameAndType.
+         *
+         * Each of these entry types contains either one or two indexes of
+         * other constant pool entries.
+         *
+         * IndirectEntry objects are used as the keys for their entries in
+         * the Map "map", so the hashCode and equals methods are overridden
+         * to allow matching.
+         */
+        private static class IndirectEntry extends Entry {
+            private int tag;
+            private short index0;
+            private short index1;
+
+            /**
+             * Construct an IndirectEntry for a constant pool entry type
+             * that contains one index of another entry.
+             */
+            public IndirectEntry(int tag, short index) {
+                this.tag = tag;
+                this.index0 = index;
+                this.index1 = 0;
+            }
+
+            /**
+             * Construct an IndirectEntry for a constant pool entry type
+             * that contains two indexes for other entries.
+             */
+            public IndirectEntry(int tag, short index0, short index1) {
+                this.tag = tag;
+                this.index0 = index0;
+                this.index1 = index1;
+            }
+
+            public void write(DataOutputStream out) throws IOException {
+                out.writeByte(tag);
+                out.writeShort(index0);
+                /*
+                 * If this entry type contains two indexes, write
+                 * out the second, too.
+                 */
+                if (tag == CONSTANT_FIELD ||
+                    tag == CONSTANT_METHOD ||
+                    tag == CONSTANT_INTERFACEMETHOD ||
+                    tag == CONSTANT_NAMEANDTYPE)
+                {
+                    out.writeShort(index1);
+                }
+            }
+
+            public int hashCode() {
+                return tag + index0 + index1;
+            }
+
+            public boolean equals(Object obj) {
+                if (obj instanceof IndirectEntry) {
+                    IndirectEntry other = (IndirectEntry) obj;
+                    if (tag == other.tag &&
+                        index0 == other.index0 && index1 == other.index1)
+                    {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+    }
+}
--- a/jdk/src/java.base/share/classes/java/security/cert/PolicyQualifierInfo.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/security/cert/PolicyQualifierInfo.java	Tue Dec 22 13:41:12 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.io.IOException;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.DerValue;
 
 /**
--- a/jdk/src/java.base/share/classes/java/security/cert/X509CertSelector.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/security/cert/X509CertSelector.java	Tue Dec 22 13:41:12 2015 -0800
@@ -31,7 +31,7 @@
 import java.util.*;
 import javax.security.auth.x500.X500Principal;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.Debug;
 import sun.security.util.DerInputStream;
 import sun.security.util.DerValue;
--- a/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1856,6 +1856,7 @@
             if (patternCharIndex == PATTERN_HOUR_OF_DAY1 ||
                 patternCharIndex == PATTERN_HOUR1 ||
                 (patternCharIndex == PATTERN_MONTH && count <= 2) ||
+                (patternCharIndex == PATTERN_MONTH_STANDALONE && count <= 2) ||
                 patternCharIndex == PATTERN_YEAR ||
                 patternCharIndex == PATTERN_WEEK_YEAR) {
                 // It would be good to unify this with the obeyCount logic below,
@@ -1976,6 +1977,20 @@
                 }
                 break parsing;
 
+            case PATTERN_MONTH_STANDALONE: // 'L'
+                if (count <= 2) {
+                    // Don't want to parse the month if it is a string
+                    // while pattern uses numeric style: L or LL
+                    //[we computed 'value' above.]
+                    calb.set(Calendar.MONTH, value - 1);
+                    return pos.index;
+                }
+                Map<String, Integer> maps = getDisplayNamesMap(field, locale);
+                if ((index = matchString(text, start, field, maps, calb)) > 0) {
+                    return index;
+                }
+                break parsing;
+
             case PATTERN_HOUR_OF_DAY1: // 'k' 1-based.  eg, 23:59 + 1 hour =>> 24:59
                 if (!isLenient()) {
                     // Validate the hour value in non-lenient
--- a/jdk/src/java.base/share/classes/java/time/Duration.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java	Tue Dec 22 13:41:12 2015 -0800
@@ -997,6 +997,24 @@
      }
 
     /**
+     * Returns number of whole times a specified Duration occurs within this Duration.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param divisor the value to divide the duration by, positive or negative, not null
+     * @return number of whole times, rounded toward zero, a specified
+     *         {@code Duration} occurs within this Duration, may be negative
+     * @throws ArithmeticException if the divisor is zero, or if numeric overflow occurs
+     * @since 9
+     */
+    public long dividedBy(Duration divisor) {
+        Objects.requireNonNull(divisor, "divisor");
+        BigDecimal dividendBigD = toBigDecimalSeconds();
+        BigDecimal divisorBigD = divisor.toBigDecimalSeconds();
+        return dividendBigD.divideToIntegralValue(divisorBigD).longValueExact();
+    }
+
+    /**
      * Converts this duration to the total length in seconds and
      * fractional nanoseconds expressed as a {@code BigDecimal}.
      *
--- a/jdk/src/java.base/share/classes/java/util/AbstractMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/AbstractMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -304,9 +304,28 @@
      * Each of these fields are initialized to contain an instance of the
      * appropriate view the first time this view is requested.  The views are
      * stateless, so there's no reason to create more than one of each.
+     *
+     * <p>Since there is no synchronization performed while accessing these fields,
+     * it is expected that java.util.Map view classes using these fields have
+     * no non-final fields (or any fields at all except for outer-this). Adhering
+     * to this rule would make the races on these fields benign.
+     *
+     * <p>It is also imperative that implementations read the field only once,
+     * as in:
+     *
+     * <pre> {@code
+     * public Set<K> keySet() {
+     *   Set<K> ks = keySet;  // single racy read
+     *   if (ks == null) {
+     *     ks = new KeySet();
+     *     keySet = ks;
+     *   }
+     *   return ks;
+     * }
+     *}</pre>
      */
-    transient volatile Set<K>        keySet;
-    transient volatile Collection<V> values;
+    transient Set<K>        keySet;
+    transient Collection<V> values;
 
     /**
      * {@inheritDoc}
@@ -325,8 +344,9 @@
      * method will not all return the same set.
      */
     public Set<K> keySet() {
-        if (keySet == null) {
-            keySet = new AbstractSet<K>() {
+        Set<K> ks = keySet;
+        if (ks == null) {
+            ks = new AbstractSet<K>() {
                 public Iterator<K> iterator() {
                     return new Iterator<K>() {
                         private Iterator<Entry<K,V>> i = entrySet().iterator();
@@ -361,8 +381,9 @@
                     return AbstractMap.this.containsKey(k);
                 }
             };
+            keySet = ks;
         }
-        return keySet;
+        return ks;
     }
 
     /**
@@ -382,8 +403,9 @@
      * method will not all return the same collection.
      */
     public Collection<V> values() {
-        if (values == null) {
-            values = new AbstractCollection<V>() {
+        Collection<V> vals = values;
+        if (vals == null) {
+            vals = new AbstractCollection<V>() {
                 public Iterator<V> iterator() {
                     return new Iterator<V>() {
                         private Iterator<Entry<K,V>> i = entrySet().iterator();
@@ -418,8 +440,9 @@
                     return AbstractMap.this.containsValue(v);
                 }
             };
+            values = vals;
         }
-        return values;
+        return vals;
     }
 
     public abstract Set<Entry<K,V>> entrySet();
--- a/jdk/src/java.base/share/classes/java/util/Collections.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Collections.java	Tue Dec 22 13:41:12 2015 -0800
@@ -5530,7 +5530,7 @@
      * @since  1.6
      */
     public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
-        return new AsLIFOQueue<>(deque);
+        return new AsLIFOQueue<>(Objects.requireNonNull(deque));
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/EnumMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/EnumMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -380,10 +380,11 @@
      */
     public Set<K> keySet() {
         Set<K> ks = keySet;
-        if (ks != null)
-            return ks;
-        else
-            return keySet = new KeySet();
+        if (ks == null) {
+            ks = new KeySet();
+            keySet = ks;
+        }
+        return ks;
     }
 
     private class KeySet extends AbstractSet<K> {
@@ -418,10 +419,11 @@
      */
     public Collection<V> values() {
         Collection<V> vs = values;
-        if (vs != null)
-            return vs;
-        else
-            return values = new Values();
+        if (vs == null) {
+            vs = new Values();
+            values = vs;
+        }
+        return vs;
     }
 
     private class Values extends AbstractCollection<V> {
--- a/jdk/src/java.base/share/classes/java/util/HashMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/HashMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -902,8 +902,12 @@
      * @return a set view of the keys contained in this map
      */
     public Set<K> keySet() {
-        Set<K> ks;
-        return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
+        Set<K> ks = keySet;
+        if (ks == null) {
+            ks = new KeySet();
+            keySet = ks;
+        }
+        return ks;
     }
 
     final class KeySet extends AbstractSet<K> {
@@ -949,8 +953,12 @@
      * @return a view of the values contained in this map
      */
     public Collection<V> values() {
-        Collection<V> vs;
-        return (vs = values) == null ? (values = new Values()) : vs;
+        Collection<V> vs = values;
+        if (vs == null) {
+            vs = new Values();
+            values = vs;
+        }
+        return vs;
     }
 
     final class Values extends AbstractCollection<V> {
--- a/jdk/src/java.base/share/classes/java/util/IdentityHashMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/IdentityHashMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -964,10 +964,11 @@
      */
     public Set<K> keySet() {
         Set<K> ks = keySet;
-        if (ks != null)
-            return ks;
-        else
-            return keySet = new KeySet();
+        if (ks == null) {
+            ks = new KeySet();
+            keySet = ks;
+        }
+        return ks;
     }
 
     private class KeySet extends AbstractSet<K> {
@@ -1069,10 +1070,11 @@
      */
     public Collection<V> values() {
         Collection<V> vs = values;
-        if (vs != null)
-            return vs;
-        else
-            return values = new Values();
+        if (vs == null) {
+            vs = new Values();
+            values = vs;
+        }
+        return vs;
     }
 
     private class Values extends AbstractCollection<V> {
--- a/jdk/src/java.base/share/classes/java/util/LinkedHashMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/LinkedHashMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -528,8 +528,12 @@
      * @return a set view of the keys contained in this map
      */
     public Set<K> keySet() {
-        Set<K> ks;
-        return (ks = keySet) == null ? (keySet = new LinkedKeySet()) : ks;
+        Set<K> ks = keySet;
+        if (ks == null) {
+            ks = new LinkedKeySet();
+            keySet = ks;
+        }
+        return ks;
     }
 
     final class LinkedKeySet extends AbstractSet<K> {
@@ -577,8 +581,12 @@
      * @return a view of the values contained in this map
      */
     public Collection<V> values() {
-        Collection<V> vs;
-        return (vs = values) == null ? (values = new LinkedValues()) : vs;
+        Collection<V> vs = values;
+        if (vs == null) {
+            vs = new LinkedValues();
+            values = vs;
+        }
+        return vs;
     }
 
     final class LinkedValues extends AbstractCollection<V> {
--- a/jdk/src/java.base/share/classes/java/util/TreeMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/TreeMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -852,7 +852,11 @@
      */
     public Collection<V> values() {
         Collection<V> vs = values;
-        return (vs != null) ? vs : (values = new Values());
+        if (vs == null) {
+            vs = new Values();
+            values = vs;
+        }
+        return vs;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/WeakHashMap.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/WeakHashMap.java	Tue Dec 22 13:41:12 2015 -0800
@@ -866,7 +866,11 @@
      */
     public Set<K> keySet() {
         Set<K> ks = keySet;
-        return (ks != null ? ks : (keySet = new KeySet()));
+        if (ks == null) {
+            ks = new KeySet();
+            keySet = ks;
+        }
+        return ks;
     }
 
     private class KeySet extends AbstractSet<K> {
@@ -915,7 +919,11 @@
      */
     public Collection<V> values() {
         Collection<V> vs = values;
-        return (vs != null) ? vs : (values = new Values());
+        if (vs == null) {
+            vs = new Values();
+            values = vs;
+        }
+        return vs;
     }
 
     private class Values extends AbstractCollection<V> {
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java	Tue Dec 22 13:41:12 2015 -0800
@@ -203,7 +203,10 @@
         return man;
     }
 
-    private native String[] getMetaInfEntryNames();
+    private String[] getMetaInfEntryNames() {
+        return jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess()
+                                              .getMetaInfEntryNames((ZipFile)this);
+    }
 
     /**
      * Returns the {@code JarEntry} for the given entry name or
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -5814,7 +5814,7 @@
      */
     public Stream<String> splitAsStream(final CharSequence input) {
         class MatcherIterator implements Iterator<String> {
-            private final Matcher matcher;
+            private Matcher matcher;
             // The start position of the next sub-sequence of input
             // when current == input.length there are no more elements
             private int current;
@@ -5823,14 +5823,6 @@
             // > 0 if there are N next empty elements
             private int emptyElementCount;
 
-            MatcherIterator() {
-                this.matcher = matcher(input);
-                // If the input is an empty string then the result can only be a
-                // stream of the input.  Induce that by setting the empty
-                // element count to 1
-                this.emptyElementCount = input.length() == 0 ? 1 : 0;
-            }
-
             public String next() {
                 if (!hasNext())
                     throw new NoSuchElementException();
@@ -5846,6 +5838,13 @@
             }
 
             public boolean hasNext() {
+                if (matcher == null) {
+                    matcher = matcher(input);
+                    // If the input is an empty string then the result can only be a
+                    // stream of the input.  Induce that by setting the empty
+                    // element count to 1
+                    emptyElementCount = input.length() == 0 ? 1 : 0;
+                }
                 if (nextElement != null || emptyElementCount > 0)
                     return true;
 
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java	Tue Dec 22 13:41:12 2015 -0800
@@ -434,7 +434,7 @@
      * stream returned by mapper
      * @return a collector which applies the mapping function to the input
      * elements and provides the flat mapped results to the downstream collector
-     * @since 1.9
+     * @since 9
      */
     public static <T, U, A, R>
     Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
@@ -452,6 +452,53 @@
     }
 
     /**
+     * Adapts a {@code Collector} to one accepting elements of the same type
+     * {@code T} by applying the predicate to each input element and only
+     * accumulating if the predicate returns {@code true}.
+     *
+     * @apiNote
+     * The {@code filtering()} collectors are most useful when used in a
+     * multi-level reduction, such as downstream of a {@code groupingBy} or
+     * {@code partitioningBy}.  For example, given a stream of
+     * {@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())));
+     * }</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
+     * threshold in some department.  Using a filtering collector as shown above
+     * would result in a mapping from that department to an empty {@code Set}.
+     * If a stream {@code filter()} operation were done instead, there would be
+     * no mapping for that department at all.
+     *
+     * @param <T> the type of the input elements
+     * @param <A> intermediate accumulation type of the downstream collector
+     * @param <R> result type of collector
+     * @param predicate a predicate to be applied to the input elements
+     * @param downstream a collector which will accept values that match the
+     * predicate
+     * @return a collector which applies the predicate to the input elements
+     * and provides matching elements to the downstream collector
+     * @since 9
+     */
+    public static <T, A, R>
+    Collector<T, ?, R> filtering(Predicate<? super T> predicate,
+                               Collector<? super T, A, R> downstream) {
+        BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
+        return new CollectorImpl<>(downstream.supplier(),
+                                   (r, t) -> {
+                                       if (predicate.test(t)) {
+                                           downstreamAccumulator.accept(r, t);
+                                       }
+                                   },
+                                   downstream.combiner(), downstream.finisher(),
+                                   downstream.characteristics());
+    }
+
+    /**
      * Adapts a {@code Collector} to perform an additional finishing
      * transformation.  For example, one could adapt the {@link #toList()}
      * collector to always produce an immutable list with:
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java	Tue Dec 22 13:41:12 2015 -0800
@@ -43,7 +43,7 @@
 
 final class ZipCoder {
 
-    String toString(byte[] ba, int length) {
+    String toString(byte[] ba, int off, int length) {
         CharsetDecoder cd = decoder().reset();
         int len = (int)(length * cd.maxCharsPerByte());
         char[] ca = new char[len];
@@ -53,12 +53,12 @@
         // CodingErrorAction.REPLACE mode. ZipCoder uses
         // REPORT mode.
         if (isUTF8 && cd instanceof ArrayDecoder) {
-            int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
+            int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca);
             if (clen == -1)    // malformed
                 throw new IllegalArgumentException("MALFORMED");
             return new String(ca, 0, clen);
         }
-        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
+        ByteBuffer bb = ByteBuffer.wrap(ba, off, length);
         CharBuffer cb = CharBuffer.wrap(ca);
         CoderResult cr = cd.decode(bb, cb, true);
         if (!cr.isUnderflow())
@@ -69,8 +69,12 @@
         return new String(ca, 0, cb.position());
     }
 
+    String toString(byte[] ba, int length) {
+        return toString(ba, 0, length);
+    }
+
     String toString(byte[] ba) {
-        return toString(ba, ba.length);
+        return toString(ba, 0, ba.length);
     }
 
     byte[] getBytes(String s) {
@@ -111,13 +115,16 @@
         return utf8.getBytes(s);
     }
 
+    String toStringUTF8(byte[] ba, int len) {
+        return toStringUTF8(ba, 0, len);
+    }
 
-    String toStringUTF8(byte[] ba, int len) {
+    String toStringUTF8(byte[] ba, int off, int len) {
         if (isUTF8)
-            return toString(ba, len);
+            return toString(ba, off, len);
         if (utf8 == null)
             utf8 = new ZipCoder(StandardCharsets.UTF_8);
-        return utf8.toString(ba, len);
+        return utf8.toString(ba, off, len);
     }
 
     boolean isUTF8() {
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,14 +30,22 @@
 import java.io.IOException;
 import java.io.EOFException;
 import java.io.File;
+import java.io.RandomAccessFile;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.Path;
+import java.nio.file.Files;
+
 import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Deque;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.Spliterator;
 import java.util.Spliterators;
@@ -47,7 +55,9 @@
 import jdk.internal.misc.JavaUtilZipFileAccess;
 import jdk.internal.misc.SharedSecrets;
 
+import static java.util.zip.ZipConstants.*;
 import static java.util.zip.ZipConstants64.*;
+import static java.util.zip.ZipUtils.*;
 
 /**
  * This class is used to read entries from a zip file.
@@ -60,11 +70,11 @@
  */
 public
 class ZipFile implements ZipConstants, Closeable {
-    private long jzfile;  // address of jzfile data
+
     private final String name;     // zip file name
-    private final int total;       // total number of entries
-    private final boolean locsig;  // if zip file starts with LOCSIG (usually true)
     private volatile boolean closeRequested = false;
+    private Source zsrc;
+    private ZipCoder zc;
 
     private static final int STORED = ZipEntry.STORED;
     private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -83,23 +93,6 @@
      */
     public static final int OPEN_DELETE = 0x4;
 
-    static {
-        /* Zip library is loaded from System.initializeSystemClass */
-        initIDs();
-    }
-
-    private static native void initIDs();
-
-    private static final boolean usemmap;
-
-    static {
-        // A system prpperty to disable mmap use to avoid vm crash when
-        // in-use zip file is accidently overwritten by others.
-        String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping");
-        usemmap = (prop == null ||
-                   !(prop.length() == 0 || prop.equalsIgnoreCase("true")));
-    }
-
     /**
      * Opens a zip file for reading.
      *
@@ -165,8 +158,6 @@
         this(file, OPEN_READ);
     }
 
-    private ZipCoder zc;
-
     /**
      * Opens a new {@code ZipFile} to read from the specified
      * {@code File} object in the specified mode.  The mode argument
@@ -214,16 +205,13 @@
                 sm.checkDelete(name);
             }
         }
-        if (charset == null)
-            throw new NullPointerException("charset is null");
+        Objects.requireNonNull(charset, "charset");
         this.zc = ZipCoder.get(charset);
+        this.name = name;
         long t0 = System.nanoTime();
-        jzfile = open(name, mode, file.lastModified(), usemmap);
+        this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
         sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
         sun.misc.PerfCounter.getZipFileCount().increment();
-        this.name = name;
-        this.total = getTotal(jzfile);
-        this.locsig = startsWithLOC(jzfile);
     }
 
     /**
@@ -257,6 +245,7 @@
 
     /**
      * Opens a ZIP file for reading given the specified File object.
+     *
      * @param file the ZIP file to be opened for reading
      * @param charset
      *        The {@linkplain java.nio.charset.Charset charset} to be
@@ -287,10 +276,10 @@
     public String getComment() {
         synchronized (this) {
             ensureOpen();
-            byte[] bcomm = getCommentBytes(jzfile);
-            if (bcomm == null)
+            if (zsrc.comment == null) {
                 return null;
-            return zc.toString(bcomm, bcomm.length);
+            }
+            return zc.toString(zsrc.comment);
         }
     }
 
@@ -303,38 +292,28 @@
      * @throws IllegalStateException if the zip file has been closed
      */
     public ZipEntry getEntry(String name) {
-        if (name == null) {
-            throw new NullPointerException("name");
-        }
-        long jzentry = 0;
+
+        Objects.requireNonNull(name, "name");
         synchronized (this) {
             ensureOpen();
-            jzentry = getEntry(jzfile, zc.getBytes(name), true);
-            if (jzentry != 0) {
-                ZipEntry ze = getZipEntry(name, jzentry);
-                freeEntry(jzfile, jzentry);
-                return ze;
+            int pos = zsrc.getEntryPos(zc.getBytes(name), true);
+            if (pos != -1) {
+                return getZipEntry(name, pos);
             }
         }
         return null;
     }
 
-    private static native long getEntry(long jzfile, byte[] name,
-                                        boolean addSlash);
-
-    // freeEntry releases the C jzentry struct.
-    private static native void freeEntry(long jzfile, long jzentry);
-
-    // the outstanding inputstreams that need to be closed,
+    // The outstanding inputstreams that need to be closed,
     // mapped to the inflater objects they use.
     private final Map<InputStream, Inflater> streams = new WeakHashMap<>();
 
     /**
      * Returns an input stream for reading the contents of the specified
      * zip file entry.
-     *
-     * <p> Closing this ZIP file will, in turn, close all input
-     * streams that have been returned by invocations of this method.
+     * <p>
+     * Closing this ZIP file will, in turn, close all input streams that
+     * have been returned by invocations of this method.
      *
      * @param entry the zip file entry
      * @return the input stream for reading the contents of the specified
@@ -344,37 +323,38 @@
      * @throws IllegalStateException if the zip file has been closed
      */
     public InputStream getInputStream(ZipEntry entry) throws IOException {
-        if (entry == null) {
-            throw new NullPointerException("entry");
-        }
-        long jzentry = 0;
+        Objects.requireNonNull(entry, "entry");
+        int pos = -1;
         ZipFileInputStream in = null;
         synchronized (this) {
             ensureOpen();
             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
-                jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
+                pos = zsrc.getEntryPos(zc.getBytesUTF8(entry.name), false);
             } else {
-                jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
+                pos = zsrc.getEntryPos(zc.getBytes(entry.name), false);
             }
-            if (jzentry == 0) {
+            if (pos == -1) {
                 return null;
             }
-            in = new ZipFileInputStream(jzentry);
-
-            switch (getEntryMethod(jzentry)) {
+            in = new ZipFileInputStream(zsrc.cen, pos);
+            switch (CENHOW(zsrc.cen, pos)) {
             case STORED:
                 synchronized (streams) {
                     streams.put(in, null);
                 }
                 return in;
             case DEFLATED:
+                // Inflater likes a bit of slack
                 // MORE: Compute good size for inflater stream:
-                long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
-                if (size > 65536) size = 8192;
-                if (size <= 0) size = 4096;
+                long size = CENLEN(zsrc.cen, pos) + 2;
+                if (size > 65536) {
+                    size = 8192;
+                }
+                if (size <= 0) {
+                    size = 4096;
+                }
                 Inflater inf = getInflater();
-                InputStream is =
-                    new ZipFileInflaterInputStream(in, inf, (int)size);
+                InputStream is = new ZipFileInflaterInputStream(in, inf, (int)size);
                 synchronized (streams) {
                     streams.put(is, inf);
                 }
@@ -447,8 +427,8 @@
     private Inflater getInflater() {
         Inflater inf;
         synchronized (inflaterCache) {
-            while (null != (inf = inflaterCache.poll())) {
-                if (false == inf.ended()) {
+            while ((inf = inflaterCache.poll()) != null) {
+                if (!inf.ended()) {
                     return inf;
                 }
             }
@@ -460,7 +440,7 @@
      * Releases the specified inflater to the list of available inflaters.
      */
     private void releaseInflater(Inflater inf) {
-        if (false == inf.ended()) {
+        if (!inf.ended()) {
             inf.reset();
             synchronized (inflaterCache) {
                 inflaterCache.add(inf);
@@ -469,7 +449,7 @@
     }
 
     // List of available Inflater objects for decompression
-    private Deque<Inflater> inflaterCache = new ArrayDeque<>();
+    private final Deque<Inflater> inflaterCache = new ArrayDeque<>();
 
     /**
      * Returns the path name of the ZIP file.
@@ -493,7 +473,7 @@
         public boolean hasNext() {
             synchronized (ZipFile.this) {
                 ensureOpen();
-                return i < total;
+                return i < zsrc.total;
             }
         }
 
@@ -504,28 +484,11 @@
         public ZipEntry next() {
             synchronized (ZipFile.this) {
                 ensureOpen();
-                if (i >= total) {
+                if (i >= zsrc.total) {
                     throw new NoSuchElementException();
                 }
-                long jzentry = getNextEntry(jzfile, i++);
-                if (jzentry == 0) {
-                    String message;
-                    if (closeRequested) {
-                        message = "ZipFile concurrently closed";
-                    } else {
-                        message = getZipMessage(ZipFile.this.jzfile);
-                    }
-                    throw new ZipError("jzentry == 0" +
-                                       ",\n jzfile = " + ZipFile.this.jzfile +
-                                       ",\n total = " + ZipFile.this.total +
-                                       ",\n name = " + ZipFile.this.name +
-                                       ",\n i = " + i +
-                                       ",\n message = " + message
-                        );
-                }
-                ZipEntry ze = getZipEntry(null, jzentry);
-                freeEntry(jzfile, jzentry);
-                return ze;
+                // each "entry" has 3 ints in table entries
+                return getZipEntry(null, zsrc.getEntryPos(i++ * 3));
             }
         }
 
@@ -559,48 +522,53 @@
                         Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
     }
 
-    private ZipEntry getZipEntry(String name, long jzentry) {
+    /* Checks ensureOpen() before invoke this method */
+    private ZipEntry getZipEntry(String name, int pos) {
+        byte[] cen = zsrc.cen;
         ZipEntry e = new ZipEntry();
-        e.flag = getEntryFlag(jzentry);  // get the flag first
+        int nlen = CENNAM(cen, pos);
+        int elen = CENEXT(cen, pos);
+        int clen = CENCOM(cen, pos);
+        e.flag = CENFLG(cen, pos);  // get the flag first
         if (name != null) {
             e.name = name;
         } else {
-            byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
-                e.name = zc.toStringUTF8(bname, bname.length);
+                e.name = zc.toStringUTF8(cen, pos + CENHDR, nlen);
             } else {
-                e.name = zc.toString(bname, bname.length);
+                e.name = zc.toString(cen, pos + CENHDR, nlen);
             }
         }
-        e.xdostime = getEntryTime(jzentry);
-        e.crc = getEntryCrc(jzentry);
-        e.size = getEntrySize(jzentry);
-        e.csize = getEntryCSize(jzentry);
-        e.method = getEntryMethod(jzentry);
-        e.setExtra0(getEntryBytes(jzentry, JZENTRY_EXTRA), false);
-        byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
-        if (bcomm == null) {
-            e.comment = null;
-        } else {
+        e.xdostime = CENTIM(cen, pos);
+        e.crc = CENCRC(cen, pos);
+        e.size = CENLEN(cen, pos);
+        e.csize = CENSIZ(cen, pos);
+        e.method = CENHOW(cen, pos);
+        if (elen != 0) {
+            e.setExtra0(Arrays.copyOfRange(cen, pos + CENHDR + nlen,
+                                           pos + CENHDR + nlen + elen), true);
+        }
+        if (clen != 0) {
             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
-                e.comment = zc.toStringUTF8(bcomm, bcomm.length);
+                e.comment = zc.toStringUTF8(cen, pos + CENHDR + nlen + elen, clen);
             } else {
-                e.comment = zc.toString(bcomm, bcomm.length);
+                e.comment = zc.toString(cen, pos + CENHDR + nlen + elen, clen);
             }
         }
         return e;
     }
 
-    private static native long getNextEntry(long jzfile, int i);
-
     /**
      * Returns the number of entries in the ZIP file.
+     *
      * @return the number of entries in the ZIP file
      * @throws IllegalStateException if the zip file has been closed
      */
     public int size() {
-        ensureOpen();
-        return total;
+        synchronized (this) {
+            ensureOpen();
+            return zsrc.total;
+        }
     }
 
     /**
@@ -612,14 +580,15 @@
      * @throws IOException if an I/O error has occurred
      */
     public void close() throws IOException {
-        if (closeRequested)
+        if (closeRequested) {
             return;
+        }
         closeRequested = true;
 
         synchronized (this) {
             // Close streams, release their inflaters
             synchronized (streams) {
-                if (false == streams.isEmpty()) {
+                if (!streams.isEmpty()) {
                     Map<InputStream, Inflater> copy = new HashMap<>(streams);
                     streams.clear();
                     for (Map.Entry<InputStream, Inflater> e : copy.entrySet()) {
@@ -631,21 +600,17 @@
                     }
                 }
             }
-
             // Release cached inflaters
-            Inflater inf;
             synchronized (inflaterCache) {
-                while (null != (inf = inflaterCache.poll())) {
+                Inflater inf;
+                while ((inf = inflaterCache.poll()) != null) {
                     inf.end();
                 }
             }
-
-            if (jzfile != 0) {
-                // Close the zip file
-                long zf = this.jzfile;
-                jzfile = 0;
-
-                close(zf);
+            // Release zip src
+            if (zsrc != null) {
+                Source.close(zsrc);
+                zsrc = null;
             }
         }
     }
@@ -668,14 +633,11 @@
         close();
     }
 
-    private static native void close(long jzfile);
-
     private void ensureOpen() {
         if (closeRequested) {
             throw new IllegalStateException("zip file closed");
         }
-
-        if (jzfile == 0) {
+        if (zsrc == null) {
             throw new IllegalStateException("The object is not initialized.");
         }
     }
@@ -691,40 +653,99 @@
      * (possibly compressed) zip file entry.
      */
    private class ZipFileInputStream extends InputStream {
-        private volatile boolean zfisCloseRequested = false;
-        protected long jzentry; // address of jzentry data
+        private volatile boolean closeRequested = false;
         private   long pos;     // current position within entry data
         protected long rem;     // number of remaining bytes within entry
         protected long size;    // uncompressed size of this entry
 
-        ZipFileInputStream(long jzentry) {
-            pos = 0;
-            rem = getEntryCSize(jzentry);
-            size = getEntrySize(jzentry);
-            this.jzentry = jzentry;
+        ZipFileInputStream(byte[] cen, int cenpos) throws IOException {
+            rem = CENSIZ(cen, cenpos);
+            size = CENLEN(cen, cenpos);
+            pos = CENOFF(cen, cenpos);
+            // zip64
+            if (rem == ZIP64_MAGICVAL || size == ZIP64_MAGICVAL ||
+                pos == ZIP64_MAGICVAL) {
+                checkZIP64(cen, cenpos);
+            }
+            // negative for lazy initialization, see getDataOffset();
+            pos = - (pos + ZipFile.this.zsrc.locpos);
+        }
+
+        private void checkZIP64(byte[] cen, int cenpos) throws IOException {
+            int off = cenpos + CENHDR + CENNAM(cen, cenpos);
+            int end = off + CENEXT(cen, cenpos);
+            while (off + 4 < end) {
+                int tag = get16(cen, off);
+                int sz = get16(cen, off + 2);
+                off += 4;
+                if (off + sz > end)         // invalid data
+                    break;
+                if (tag == EXTID_ZIP64) {
+                    if (size == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > end)
+                            break;
+                        size = get64(cen, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    if (rem == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > end)
+                            break;
+                        rem = get64(cen, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    if (pos == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > end)
+                            break;
+                        pos = get64(cen, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    break;
+                }
+                off += sz;
+            }
+        }
+
+       /* The Zip file spec explicitly allows the LOC extra data size to
+        * be different from the CEN extra data size. Since we cannot trust
+        * the CEN extra data size, we need to read the LOC to determine
+        * the entry data offset.
+        */
+        private long initDataOffset() throws IOException {
+            if (pos <= 0) {
+                byte[] loc = new byte[LOCHDR];
+                pos = -pos;
+                int len = ZipFile.this.zsrc.readFullyAt(loc, 0, loc.length, pos);
+                if (len != LOCHDR) {
+                    throw new ZipException("ZipFile error reading zip file");
+                }
+                if (LOCSIG(loc) != LOCSIG) {
+                    throw new ZipException("ZipFile invalid LOC header (bad signature)");
+                }
+                pos += LOCHDR + LOCNAM(loc) + LOCEXT(loc);
+            }
+            return pos;
         }
 
         public int read(byte b[], int off, int len) throws IOException {
             synchronized (ZipFile.this) {
-                long rem = this.rem;
-                long pos = this.pos;
+                ensureOpenOrZipException();
+                initDataOffset();
                 if (rem == 0) {
                     return -1;
                 }
+                if (len > rem) {
+                    len = (int) rem;
+                }
                 if (len <= 0) {
                     return 0;
                 }
-                if (len > rem) {
-                    len = (int) rem;
-                }
-
-                // Check if ZipFile open
-                ensureOpenOrZipException();
-                len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
-                                   off, len);
+                len = ZipFile.this.zsrc.readAt(b, off, len, pos);
                 if (len > 0) {
-                    this.pos = (pos + len);
-                    this.rem = (rem - len);
+                    pos += len;
+                    rem -= len;
                 }
             }
             if (rem == 0) {
@@ -742,11 +763,16 @@
             }
         }
 
-        public long skip(long n) {
-            if (n > rem)
-                n = rem;
-            pos += n;
-            rem -= n;
+        public long skip(long n) throws IOException {
+            synchronized (ZipFile.this) {
+                ensureOpenOrZipException();
+                initDataOffset();
+                if (n > rem) {
+                    n = rem;
+                }
+                pos += n;
+                rem -= n;
+            }
             if (rem == 0) {
                 close();
             }
@@ -762,17 +788,11 @@
         }
 
         public void close() {
-            if (zfisCloseRequested)
+            if (closeRequested) {
                 return;
-            zfisCloseRequested = true;
-
+            }
+            closeRequested = true;
             rem = 0;
-            synchronized (ZipFile.this) {
-                if (jzentry != 0 && ZipFile.this.jzfile != 0) {
-                    freeEntry(ZipFile.this.jzfile, jzentry);
-                    jzentry = 0;
-                }
-            }
             synchronized (streams) {
                 streams.remove(this);
             }
@@ -787,40 +807,502 @@
         SharedSecrets.setJavaUtilZipFileAccess(
             new JavaUtilZipFileAccess() {
                 public boolean startsWithLocHeader(ZipFile zip) {
-                    return zip.startsWithLocHeader();
+                    return zip.zsrc.startsWithLoc;
                 }
-            }
+                public String[] getMetaInfEntryNames(ZipFile zip) {
+                    return zip.getMetaInfEntryNames();
+                }
+             }
         );
     }
 
-    /**
-     * Returns {@code true} if, and only if, the zip file begins with {@code
-     * LOCSIG}.
+    /*
+     * Returns an array of strings representing the names of all entries
+     * that begin with "META-INF/" (case ignored). This method is used
+     * in JarFile, via SharedSecrets, as an optimization when looking up
+     * manifest and signature file entries. Returns null if no entries
+     * were found.
      */
-    private boolean startsWithLocHeader() {
-        return locsig;
+    private String[] getMetaInfEntryNames() {
+        synchronized (this) {
+            ensureOpen();
+            if (zsrc.metanames.size() == 0) {
+                return null;
+            }
+            String[] names = new String[zsrc.metanames.size()];
+            byte[] cen = zsrc.cen;
+            for (int i = 0; i < names.length; i++) {
+                int pos = zsrc.metanames.get(i);
+                names[i] = new String(cen, pos + CENHDR,  CENNAM(cen, pos),
+                                      StandardCharsets.UTF_8);
+            }
+            return names;
+        }
     }
 
-    private static native long open(String name, int mode, long lastModified,
-                                    boolean usemmap) throws IOException;
-    private static native int getTotal(long jzfile);
-    private static native boolean startsWithLOC(long jzfile);
-    private static native int read(long jzfile, long jzentry,
-                                   long pos, byte[] b, int off, int len);
+    private static class Source {
+        private final Key key;               // the key in files
+        private int refs = 1;
+
+        private RandomAccessFile zfile;      // zfile of the underlying zip file
+        private byte[] cen;                  // CEN & ENDHDR
+        private long locpos;                 // position of first LOC header (usually 0)
+        private byte[] comment;              // zip file comment
+                                             // list of meta entries in META-INF dir
+        private ArrayList<Integer> metanames = new ArrayList<>();
+        private final boolean startsWithLoc; // true, if zip file starts with LOCSIG (usually true)
+
+        // A Hashmap for all entries.
+        //
+        // A cen entry of Zip/JAR file. As we have one for every entry in every active Zip/JAR,
+        // We might have a lot of these in a typical system. In order to save space we don't
+        // keep the name in memory, but merely remember a 32 bit {@code hash} value of the
+        // entry name and its offset {@code pos} in the central directory hdeader.
+        //
+        // private static class Entry {
+        //     int hash;       // 32 bit hashcode on name
+        //     int next;       // hash chain: index into entries
+        //     int pos;        // Offset of central directory file header
+        // }
+        // private Entry[] entries;             // array of hashed cen entry
+        //
+        // To reduce the total size of entries further, we use a int[] here to store 3 "int"
+        // {@code hash}, {@code next and {@code "pos for each entry. The entry can then be
+        // referred by their index of their positions in the {@code entries}.
+        //
+        private int[] entries;                  // array of hashed cen entry
+        private int addEntry(int index, int hash, int next, int pos) {
+            entries[index++] = hash;
+            entries[index++] = next;
+            entries[index++] = pos;
+            return index;
+        }
+        private int getEntryHash(int index) { return entries[index]; }
+        private int getEntryNext(int index) { return entries[index + 1]; }
+        private int getEntryPos(int index)  { return entries[index + 2]; }
+        private static final int ZIP_ENDCHAIN  = -1;
+        private int total;                   // total number of entries
+        private int[] table;                 // Hash chain heads: indexes into entries
+        private int tablelen;                // number of hash heads
+
+        private static class Key {
+            BasicFileAttributes attrs;
+            File file;
+
+            public Key(File file, BasicFileAttributes attrs) {
+                this.attrs = attrs;
+                this.file = file;
+            }
+
+            public int hashCode() {
+                long t = attrs.lastModifiedTime().toMillis();
+                return ((int)(t ^ (t >>> 32))) + file.hashCode();
+            }
+
+            public boolean equals(Object obj) {
+                if (obj instanceof Key) {
+                    Key key = (Key)obj;
+                    if (!attrs.lastModifiedTime().equals(key.attrs.lastModifiedTime())) {
+                        return false;
+                    }
+                    Object fk = attrs.fileKey();
+                    if (fk != null) {
+                        return  fk.equals(key.attrs.fileKey());
+                    } else {
+                        return file.equals(key.file);
+                    }
+                }
+                return false;
+            }
+        }
+        private static final HashMap<Key, Source> files = new HashMap<>();
+
+
+        public static Source get(File file, boolean toDelete) throws IOException {
+            Key key = new Key(file,
+                              Files.readAttributes(file.toPath(), BasicFileAttributes.class));
+            Source src = null;
+            synchronized (files) {
+                src = files.get(key);
+                if (src != null) {
+                    src.refs++;
+                    return src;
+                }
+            }
+            src = new Source(key, toDelete);
+
+            synchronized (files) {
+                if (files.containsKey(key)) {    // someone else put in first
+                    src.close();                 // close the newly created one
+                    src = files.get(key);
+                    src.refs++;
+                    return src;
+                }
+                files.put(key, src);
+                return src;
+            }
+        }
+
+        private static void close(Source src) throws IOException {
+            synchronized (files) {
+                if (--src.refs == 0) {
+                    files.remove(src.key);
+                    src.close();
+                }
+            }
+        }
+
+        private Source(Key key, boolean toDelete) throws IOException {
+            this.key = key;
+            this.zfile = new RandomAccessFile(key.file, "r");
+            if (toDelete) {
+                key.file.delete();
+            }
+            try {
+                initCEN(-1);
+                byte[] buf = new byte[4];
+                readFullyAt(buf, 0, 4, 0);
+                this.startsWithLoc = (LOCSIG(buf) == LOCSIG);
+            } catch (IOException x) {
+                try {
+                    this.zfile.close();
+                } catch (IOException xx) {}
+                throw x;
+            }
+        }
+
+        private void close() throws IOException {
+            zfile.close();
+            zfile = null;
+            cen = null;
+            entries = null;
+            table = null;
+            metanames = null;
+        }
+
+        private static final int BUF_SIZE = 8192;
+        private final int readFullyAt(byte[] buf, int off, int len, long pos)
+            throws IOException
+        {
+            synchronized(zfile) {
+                zfile.seek(pos);
+                int N = len;
+                while (N > 0) {
+                    int n = Math.min(BUF_SIZE, N);
+                    zfile.readFully(buf, off, n);
+                    off += n;
+                    N -= n;
+                }
+                return len;
+            }
+        }
+
+        private final int readAt(byte[] buf, int off, int len, long pos)
+            throws IOException
+        {
+            synchronized(zfile) {
+                zfile.seek(pos);
+                return zfile.read(buf, off, len);
+            }
+        }
+
+        private static final int hashN(byte[] a, int off, int len) {
+            int h = 1;
+            while (len-- > 0) {
+                h = 31 * h + a[off++];
+            }
+            return h;
+        }
+
+        private static final int hash_append(int hash, byte b) {
+            return hash * 31 + b;
+        }
+
+        private static class End {
+            int  centot;     // 4 bytes
+            long cenlen;     // 4 bytes
+            long cenoff;     // 4 bytes
+            long endpos;     // 4 bytes
+        }
 
-    // access to the native zentry object
-    private static native long getEntryTime(long jzentry);
-    private static native long getEntryCrc(long jzentry);
-    private static native long getEntryCSize(long jzentry);
-    private static native long getEntrySize(long jzentry);
-    private static native int getEntryMethod(long jzentry);
-    private static native int getEntryFlag(long jzentry);
-    private static native byte[] getCommentBytes(long jzfile);
+        /*
+         * Searches for end of central directory (END) header. The contents of
+         * the END header will be read and placed in endbuf. Returns the file
+         * position of the END header, otherwise returns -1 if the END header
+         * was not found or an error occurred.
+         */
+        private End findEND() throws IOException {
+            long ziplen = zfile.length();
+            if (ziplen <= 0)
+                zerror("zip file is empty");
+            End end = new End();
+            byte[] buf = new byte[READBLOCKSZ];
+            long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
+            long minPos = minHDR - (buf.length - ENDHDR);
+            for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) {
+                int off = 0;
+                if (pos < 0) {
+                    // Pretend there are some NUL bytes before start of file
+                    off = (int)-pos;
+                    Arrays.fill(buf, 0, off, (byte)0);
+                }
+                int len = buf.length - off;
+                if (readFullyAt(buf, off, len, pos + off) != len ) {
+                    zerror("zip END header not found");
+                }
+                // Now scan the block backwards for END header signature
+                for (int i = buf.length - ENDHDR; i >= 0; i--) {
+                    if (buf[i+0] == (byte)'P'    &&
+                        buf[i+1] == (byte)'K'    &&
+                        buf[i+2] == (byte)'\005' &&
+                        buf[i+3] == (byte)'\006') {
+                        // Found ENDSIG header
+                        byte[] endbuf = Arrays.copyOfRange(buf, i, i + ENDHDR);
+                        end.centot = ENDTOT(endbuf);
+                        end.cenlen = ENDSIZ(endbuf);
+                        end.cenoff = ENDOFF(endbuf);
+                        end.endpos = pos + i;
+                        int comlen = ENDCOM(endbuf);
+                        if (end.endpos + ENDHDR + comlen != ziplen) {
+                            // ENDSIG matched, however the size of file comment in it does
+                            // not match the real size. One "common" cause for this problem
+                            // is some "extra" bytes are padded at the end of the zipfile.
+                            // Let's do some extra verification, we don't care about the
+                            // performance in this situation.
+                            byte[] sbuf = new byte[4];
+                            long cenpos = end.endpos - end.cenlen;
+                            long locpos = cenpos - end.cenoff;
+                            if  (cenpos < 0 ||
+                                 locpos < 0 ||
+                                 readFullyAt(sbuf, 0, sbuf.length, cenpos) != 4 ||
+                                 GETSIG(sbuf) != CENSIG ||
+                                 readFullyAt(sbuf, 0, sbuf.length, locpos) != 4 ||
+                                 GETSIG(sbuf) != LOCSIG) {
+                                continue;
+                            }
+                        }
+                        if (comlen > 0) {    // this zip file has comlen
+                            comment = new byte[comlen];
+                            if (readFullyAt(comment, 0, comlen, end.endpos + ENDHDR) != comlen) {
+                                zerror("zip comment read failed");
+                            }
+                        }
+                        if (end.cenlen == ZIP64_MAGICVAL ||
+                            end.cenoff == ZIP64_MAGICVAL ||
+                            end.centot == ZIP64_MAGICCOUNT)
+                        {
+                            // need to find the zip64 end;
+                            try {
+                                byte[] loc64 = new byte[ZIP64_LOCHDR];
+                                if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
+                                    != loc64.length || GETSIG(loc64) != ZIP64_LOCSIG) {
+                                    return end;
+                                }
+                                long end64pos = ZIP64_LOCOFF(loc64);
+                                byte[] end64buf = new byte[ZIP64_ENDHDR];
+                                if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
+                                    != end64buf.length || GETSIG(end64buf) != ZIP64_ENDSIG) {
+                                    return end;
+                                }
+                                // end64 found, re-calcualte everything.
+                                end.cenlen = ZIP64_ENDSIZ(end64buf);
+                                end.cenoff = ZIP64_ENDOFF(end64buf);
+                                end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
+                                end.endpos = end64pos;
+                            } catch (IOException x) {}    // no zip64 loc/end
+                        }
+                        return end;
+                    }
+                }
+            }
+            zerror("zip END header not found");
+            return null; //make compiler happy
+        }
+
+        // Reads zip file central directory.
+        private void initCEN(int knownTotal) throws IOException {
+            if (knownTotal == -1) {
+                End end = findEND();
+                if (end.endpos == 0) {
+                    locpos = 0;
+                    total = 0;
+                    entries  = new int[0];
+                    cen = null;
+                    return;         // only END header present
+                }
+                if (end.cenlen > end.endpos)
+                    zerror("invalid END header (bad central directory size)");
+                long cenpos = end.endpos - end.cenlen;     // position of CEN table
+                // Get position of first local file (LOC) header, taking into
+                // account that there may be a stub prefixed to the zip file.
+                locpos = cenpos - end.cenoff;
+                if (locpos < 0) {
+                    zerror("invalid END header (bad central directory offset)");
+                }
+                // read in the CEN and END
+                cen = new byte[(int)(end.cenlen + ENDHDR)];
+                if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
+                    zerror("read CEN tables failed");
+                }
+                total = end.centot;
+            } else {
+                total = knownTotal;
+            }
+            // hash table for entries
+            entries  = new int[total * 3];
+            tablelen = ((total/2) | 1); // Odd -> fewer collisions
+            table    =  new int[tablelen];
+            Arrays.fill(table, ZIP_ENDCHAIN);
+            int idx = 0;
+            int hash = 0;
+            int next = -1;
+
+            // list for all meta entries
+            metanames = new ArrayList<>();
 
-    private static final int JZENTRY_NAME = 0;
-    private static final int JZENTRY_EXTRA = 1;
-    private static final int JZENTRY_COMMENT = 2;
-    private static native byte[] getEntryBytes(long jzentry, int type);
+            // Iterate through the entries in the central directory
+            int i = 0;
+            int hsh = 0;
+            int pos = 0;
+            int limit = cen.length - ENDHDR;
+            while (pos + CENHDR  <= limit) {
+                if (i >= total) {
+                    // This will only happen if the zip file has an incorrect
+                    // ENDTOT field, which usually means it contains more than
+                    // 65535 entries.
+                    initCEN(countCENHeaders(cen, limit));
+                    return;
+                }
+                if (CENSIG(cen, pos) != CENSIG)
+                    zerror("invalid CEN header (bad signature)");
+                int method = CENHOW(cen, pos);
+                int nlen   = CENNAM(cen, pos);
+                int elen   = CENEXT(cen, pos);
+                int clen   = CENCOM(cen, pos);
+                if ((CENFLG(cen, pos) & 1) != 0)
+                    zerror("invalid CEN header (encrypted entry)");
+                if (method != STORED && method != DEFLATED)
+                    zerror("invalid CEN header (bad compression method: " + method + ")");
+                if (pos + CENHDR + nlen > limit)
+                    zerror("invalid CEN header (bad header size)");
+                // Record the CEN offset and the name hash in our hash cell.
+                hash = hashN(cen, pos + CENHDR, nlen);
+                hsh = (hash & 0x7fffffff) % tablelen;
+                next = table[hsh];
+                table[hsh] = idx;
+                idx = addEntry(idx, hash, next, pos);
+                // Adds name to metanames.
+                if (isMetaName(cen, pos + CENHDR, nlen)) {
+                    metanames.add(pos);
+                }
+                // skip ext and comment
+                pos += (CENHDR + nlen + elen + clen);
+                i++;
+            }
+            total = i;
+            if (pos + ENDHDR != cen.length) {
+                zerror("invalid CEN header (bad header size)");
+            }
+        }
+
+        private static void zerror(String msg) throws ZipException {
+            throw new ZipException(msg);
+        }
 
-    private static native String getZipMessage(long jzfile);
+        /*
+         * Returns the {@code pos} of the zip cen entry corresponding to the
+         * specified entry name, or -1 if not found.
+         */
+        private int getEntryPos(byte[] name, boolean addSlash) {
+            if (total == 0) {
+                return -1;
+            }
+            int hsh = hashN(name, 0, name.length);
+            int idx = table[(hsh & 0x7fffffff) % tablelen];
+            /*
+             * This while loop is an optimization where a double lookup
+             * for name and name+/ is being performed. The name char
+             * array has enough room at the end to try again with a
+             * slash appended if the first table lookup does not succeed.
+             */
+            while(true) {
+                /*
+                 * Search down the target hash chain for a entry whose
+                 * 32 bit hash matches the hashed name.
+                 */
+                while (idx != ZIP_ENDCHAIN) {
+                    if (getEntryHash(idx) == hsh) {
+                        // The CEN name must match the specfied one
+                        int pos = getEntryPos(idx);
+                        if (name.length == CENNAM(cen, pos)) {
+                            boolean matched = true;
+                            int nameoff = pos + CENHDR;
+                            for (int i = 0; i < name.length; i++) {
+                                if (name[i] != cen[nameoff++]) {
+                                    matched = false;
+                                    break;
+                                }
+                            }
+                            if (matched) {
+                                return pos;
+                            }
+                         }
+                    }
+                    idx = getEntryNext(idx);
+                }
+                /* If not addSlash, or slash is already there, we are done */
+                if (!addSlash  || name[name.length - 1] == '/') {
+                     return -1;
+                }
+                /* Add slash and try once more */
+                name = Arrays.copyOf(name, name.length + 1);
+                name[name.length - 1] = '/';
+                hsh = hash_append(hsh, (byte)'/');
+                //idx = table[hsh % tablelen];
+                idx = table[(hsh & 0x7fffffff) % tablelen];
+                addSlash = false;
+            }
+        }
+
+        private static byte[] metainf = new byte[] {
+            'M', 'E', 'T', 'A', '-', 'I' , 'N', 'F', '/',
+        };
+
+        /*
+         * Returns true if the specified entry's name begins with the string
+         * "META-INF/" irrespective of case.
+         */
+        private static boolean isMetaName(byte[] name,  int off, int len) {
+            if (len < 9 || (name[off] != 'M' && name[off] != 'm')) {  //  sizeof("META-INF/") - 1
+                return false;
+            }
+            off++;
+            for (int i = 1; i < metainf.length; i++) {
+                byte c = name[off++];
+                // Avoid toupper; it's locale-dependent
+                if (c >= 'a' && c <= 'z') {
+                    c += 'A' - 'a';
+                }
+                if (metainf[i] != c) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /*
+         * Counts the number of CEN headers in a central directory extending
+         * from BEG to END.  Might return a bogus answer if the zip file is
+         * corrupt, but will not crash.
+         */
+        static int countCENHeaders(byte[] cen, int end) {
+            int count = 0;
+            int pos = 0;
+            while (pos + CENHDR <= end) {
+                count++;
+                pos += (CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos));
+            }
+            return count;
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java	Tue Dec 22 13:41:12 2015 -0800
@@ -31,6 +31,8 @@
 import java.time.ZoneId;
 import java.util.concurrent.TimeUnit;
 
+import static java.util.zip.ZipConstants.ENDHDR;
+
 class ZipUtils {
 
     // used to adjust values between Windows and java epoch
@@ -133,7 +135,7 @@
      * The bytes are assumed to be in Intel (little-endian) byte order.
      */
     public static final int get16(byte b[], int off) {
-        return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
+        return (b[off] & 0xff) | ((b[off + 1] & 0xff) << 8);
     }
 
     /**
@@ -160,4 +162,79 @@
     public static final int get32S(byte b[], int off) {
         return (get16(b, off) | (get16(b, off+2) << 16));
     }
+
+    // fields access methods
+    static final int CH(byte[] b, int n) {
+        return b[n] & 0xff ;
+    }
+
+    static final int SH(byte[] b, int n) {
+        return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
+    }
+
+    static final long LG(byte[] b, int n) {
+        return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
+    }
+
+    static final long LL(byte[] b, int n) {
+        return (LG(b, n)) | (LG(b, n + 4) << 32);
+    }
+
+    static final long GETSIG(byte[] b) {
+        return LG(b, 0);
+    }
+
+    // local file (LOC) header fields
+    static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
+    static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
+    static final int  LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
+    static final int  LOCHOW(byte[] b) { return SH(b, 8); } // compression method
+    static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
+    static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
+    static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
+    static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
+    static final int  LOCNAM(byte[] b) { return SH(b, 26);} // filename length
+    static final int  LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
+
+    // extra local (EXT) header fields
+    static final long EXTCRC(byte[] b) { return LG(b, 4);}  // crc of uncompressed data
+    static final long EXTSIZ(byte[] b) { return LG(b, 8);}  // compressed size
+    static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
+
+    // end of central directory header (END) fields
+    static final int  ENDSUB(byte[] b) { return SH(b, 8); }  // number of entries on this disk
+    static final int  ENDTOT(byte[] b) { return SH(b, 10);}  // total number of entries
+    static final long ENDSIZ(byte[] b) { return LG(b, 12);}  // central directory size
+    static final long ENDOFF(byte[] b) { return LG(b, 16);}  // central directory offset
+    static final int  ENDCOM(byte[] b) { return SH(b, 20);}  // size of zip file comment
+    static final int  ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
+
+    // zip64 end of central directory recoder fields
+    static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);}  // total number of entries on disk
+    static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);}  // total number of entries
+    static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);}  // central directory size
+    static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);}  // central directory offset
+    static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);}   // zip64 end offset
+
+    // central directory header (CEN) fields
+    static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
+    static final int  CENVEM(byte[] b, int pos) { return SH(b, pos + 4); }
+    static final int  CENVER(byte[] b, int pos) { return SH(b, pos + 6); }
+    static final int  CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
+    static final int  CENHOW(byte[] b, int pos) { return SH(b, pos + 10);}
+    static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);}
+    static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
+    static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);}
+    static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);}
+    static final int  CENNAM(byte[] b, int pos) { return SH(b, pos + 28);}
+    static final int  CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
+    static final int  CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
+    static final int  CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
+    static final int  CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
+    static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
+    static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
+
+    // The END header is followed by a variable length comment of size < 64k.
+    static final long END_MAXLEN = 0xFFFF + ENDHDR;
+    static final int READBLOCKSZ = 128;
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,5 +29,6 @@
 
 public interface JavaUtilZipFileAccess {
     public boolean startsWithLocHeader(ZipFile zip);
+    public String[] getMetaInfEntryNames(ZipFile zip);
 }
 
--- a/jdk/src/java.base/share/classes/sun/misc/BASE64Decoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-import java.io.PrintStream;
-
-/**
- * This class implements a BASE64 Character decoder as specified in RFC1521.
- *
- * This RFC is part of the MIME specification which is published by the
- * Internet Engineering Task Force (IETF). Unlike some other encoding
- * schemes there is nothing in this encoding that tells the decoder
- * where a buffer starts or stops, so to use it you will need to isolate
- * your encoded data into a single chunk and then feed them this decoder.
- * The simplest way to do that is to read all of the encoded data into a
- * string and then use:
- * <pre>
- *      byte    mydata[];
- *      BASE64Decoder base64 = new BASE64Decoder();
- *
- *      mydata = base64.decodeBuffer(bufferString);
- * </pre>
- * This will decode the String in <i>bufferString</i> and give you an array
- * of bytes in the array <i>myData</i>.
- *
- * On errors, this class throws a CEFormatException with the following detail
- * strings:
- * <pre>
- *    "BASE64Decoder: Not enough bytes for an atom."
- * </pre>
- *
- * @author      Chuck McManis
- * @see         CharacterEncoder
- * @see         BASE64Decoder
- */
-
-public class BASE64Decoder extends CharacterDecoder {
-
-    /** This class has 4 bytes per atom */
-    protected int bytesPerAtom() {
-        return (4);
-    }
-
-    /** Any multiple of 4 will do, 72 might be common */
-    protected int bytesPerLine() {
-        return (72);
-    }
-
-    /**
-     * This character array provides the character to value map
-     * based on RFC1521.
-     */
-    private static final char pem_array[] = {
-        //       0   1   2   3   4   5   6   7
-                'A','B','C','D','E','F','G','H', // 0
-                'I','J','K','L','M','N','O','P', // 1
-                'Q','R','S','T','U','V','W','X', // 2
-                'Y','Z','a','b','c','d','e','f', // 3
-                'g','h','i','j','k','l','m','n', // 4
-                'o','p','q','r','s','t','u','v', // 5
-                'w','x','y','z','0','1','2','3', // 6
-                '4','5','6','7','8','9','+','/'  // 7
-        };
-
-    private static final byte pem_convert_array[] = new byte[256];
-
-    static {
-        for (int i = 0; i < 255; i++) {
-            pem_convert_array[i] = -1;
-        }
-        for (int i = 0; i < pem_array.length; i++) {
-            pem_convert_array[pem_array[i]] = (byte) i;
-        }
-    }
-
-    byte decode_buffer[] = new byte[4];
-
-    /**
-     * Decode one BASE64 atom into 1, 2, or 3 bytes of data.
-     */
-    @SuppressWarnings("fallthrough")
-    protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int rem)
-        throws java.io.IOException
-    {
-        int     i;
-        byte    a = -1, b = -1, c = -1, d = -1;
-
-        if (rem < 2) {
-            throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom.");
-        }
-        do {
-            i = inStream.read();
-            if (i == -1) {
-                throw new CEStreamExhausted();
-            }
-        } while (i == '\n' || i == '\r');
-        decode_buffer[0] = (byte) i;
-
-        i = readFully(inStream, decode_buffer, 1, rem-1);
-        if (i == -1) {
-            throw new CEStreamExhausted();
-        }
-
-        if (rem > 3 && decode_buffer[3] == '=') {
-            rem = 3;
-        }
-        if (rem > 2 && decode_buffer[2] == '=') {
-            rem = 2;
-        }
-        switch (rem) {
-        case 4:
-            d = pem_convert_array[decode_buffer[3] & 0xff];
-            // NOBREAK
-        case 3:
-            c = pem_convert_array[decode_buffer[2] & 0xff];
-            // NOBREAK
-        case 2:
-            b = pem_convert_array[decode_buffer[1] & 0xff];
-            a = pem_convert_array[decode_buffer[0] & 0xff];
-            break;
-        }
-
-        switch (rem) {
-        case 2:
-            outStream.write( (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
-            break;
-        case 3:
-            outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
-            outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );
-            break;
-        case 4:
-            outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );
-            outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );
-            outStream.write( (byte) (((c << 6) & 0xc0) | (d  & 0x3f)) );
-            break;
-        }
-        return;
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/BASE64Encoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-
-/**
- * This class implements a BASE64 Character encoder as specified in RFC1521.
- * This RFC is part of the MIME specification as published by the Internet
- * Engineering Task Force (IETF). Unlike some other encoding schemes there
- * is nothing in this encoding that indicates
- * where a buffer starts or ends.
- *
- * This means that the encoded text will simply start with the first line
- * of encoded text and end with the last line of encoded text.
- *
- * @author      Chuck McManis
- * @see         CharacterEncoder
- * @see         BASE64Decoder
- */
-
-public class BASE64Encoder extends CharacterEncoder {
-
-    /** this class encodes three bytes per atom. */
-    protected int bytesPerAtom() {
-        return (3);
-    }
-
-    /**
-     * this class encodes 57 bytes per line. This results in a maximum
-     * of 57/3 * 4 or 76 characters per output line. Not counting the
-     * line termination.
-     */
-    protected int bytesPerLine() {
-        return (57);
-    }
-
-    /** This array maps the characters to their 6 bit values */
-    private static final char pem_array[] = {
-        //       0   1   2   3   4   5   6   7
-                'A','B','C','D','E','F','G','H', // 0
-                'I','J','K','L','M','N','O','P', // 1
-                'Q','R','S','T','U','V','W','X', // 2
-                'Y','Z','a','b','c','d','e','f', // 3
-                'g','h','i','j','k','l','m','n', // 4
-                'o','p','q','r','s','t','u','v', // 5
-                'w','x','y','z','0','1','2','3', // 6
-                '4','5','6','7','8','9','+','/'  // 7
-        };
-
-    /**
-     * encodeAtom - Take three bytes of input and encode it as 4
-     * printable characters. Note that if the length in len is less
-     * than three is encodes either one or two '=' signs to indicate
-     * padding characters.
-     */
-    protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len)
-        throws IOException {
-        byte a, b, c;
-
-        if (len == 1) {
-            a = data[offset];
-            b = 0;
-            c = 0;
-            outStream.write(pem_array[(a >>> 2) & 0x3F]);
-            outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
-            outStream.write('=');
-            outStream.write('=');
-        } else if (len == 2) {
-            a = data[offset];
-            b = data[offset+1];
-            c = 0;
-            outStream.write(pem_array[(a >>> 2) & 0x3F]);
-            outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
-            outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
-            outStream.write('=');
-        } else {
-            a = data[offset];
-            b = data[offset+1];
-            c = data[offset+2];
-            outStream.write(pem_array[(a >>> 2) & 0x3F]);
-            outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
-            outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
-            outStream.write(pem_array[c & 0x3F]);
-        }
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/CharacterDecoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * This class defines the decoding half of character encoders.
- * A character decoder is an algorithim for transforming 8 bit
- * binary data that has been encoded into text by a character
- * encoder, back into original binary form.
- *
- * The character encoders, in general, have been structured
- * around a central theme that binary data can be encoded into
- * text that has the form:
- *
- * <pre>
- *      [Buffer Prefix]
- *      [Line Prefix][encoded data atoms][Line Suffix]
- *      [Buffer Suffix]
- * </pre>
- *
- * Of course in the simplest encoding schemes, the buffer has no
- * distinct prefix of suffix, however all have some fixed relationship
- * between the text in an 'atom' and the binary data itself.
- *
- * In the CharacterEncoder and CharacterDecoder classes, one complete
- * chunk of data is referred to as a <i>buffer</i>. Encoded buffers
- * are all text, and decoded buffers (sometimes just referred to as
- * buffers) are binary octets.
- *
- * To create a custom decoder, you must, at a minimum,  overide three
- * abstract methods in this class.
- * <DL>
- * <DD>bytesPerAtom which tells the decoder how many bytes to
- * expect from decodeAtom
- * <DD>decodeAtom which decodes the bytes sent to it as text.
- * <DD>bytesPerLine which tells the encoder the maximum number of
- * bytes per line.
- * </DL>
- *
- * In general, the character decoders return error in the form of a
- * CEFormatException. The syntax of the detail string is
- * <pre>
- *      DecoderClassName: Error message.
- * </pre>
- *
- * Several useful decoders have already been written and are
- * referenced in the See Also list below.
- *
- * @author      Chuck McManis
- * @see         CEFormatException
- * @see         CharacterEncoder
- * @see         UCDecoder
- * @see         UUDecoder
- * @see         BASE64Decoder
- */
-
-public abstract class CharacterDecoder {
-
-    /** Return the number of bytes per atom of decoding */
-    protected abstract int bytesPerAtom();
-
-    /** Return the maximum number of bytes that can be encoded per line */
-    protected abstract int bytesPerLine();
-
-    /** decode the beginning of the buffer, by default this is a NOP. */
-    protected void decodeBufferPrefix(PushbackInputStream aStream, OutputStream bStream) throws IOException { }
-
-    /** decode the buffer suffix, again by default it is a NOP. */
-    protected void decodeBufferSuffix(PushbackInputStream aStream, OutputStream bStream) throws IOException { }
-
-    /**
-     * This method should return, if it knows, the number of bytes
-     * that will be decoded. Many formats such as uuencoding provide
-     * this information. By default we return the maximum bytes that
-     * could have been encoded on the line.
-     */
-    protected int decodeLinePrefix(PushbackInputStream aStream, OutputStream bStream) throws IOException {
-        return (bytesPerLine());
-    }
-
-    /**
-     * This method post processes the line, if there are error detection
-     * or correction codes in a line, they are generally processed by
-     * this method. The simplest version of this method looks for the
-     * (newline) character.
-     */
-    protected void decodeLineSuffix(PushbackInputStream aStream, OutputStream bStream) throws IOException { }
-
-    /**
-     * This method does an actual decode. It takes the decoded bytes and
-     * writes them to the OutputStream. The integer <i>l</i> tells the
-     * method how many bytes are required. This is always {@literal <=} bytesPerAtom().
-     */
-    protected void decodeAtom(PushbackInputStream aStream, OutputStream bStream, int l) throws IOException {
-        throw new CEStreamExhausted();
-    }
-
-    /**
-     * This method works around the bizarre semantics of BufferedInputStream's
-     * read method.
-     */
-    protected int readFully(InputStream in, byte buffer[], int offset, int len)
-        throws java.io.IOException {
-        for (int i = 0; i < len; i++) {
-            int q = in.read();
-            if (q == -1)
-                return ((i == 0) ? -1 : i);
-            buffer[i+offset] = (byte)q;
-        }
-        return len;
-    }
-
-    /**
-     * Decode the text from the InputStream and write the decoded
-     * octets to the OutputStream. This method runs until the stream
-     * is exhausted.
-     * @exception CEFormatException An error has occurred while decoding
-     * @exception CEStreamExhausted The input stream is unexpectedly out of data
-     */
-    public void decodeBuffer(InputStream aStream, OutputStream bStream) throws IOException {
-        int     i;
-        int     totalBytes = 0;
-
-        PushbackInputStream ps = new PushbackInputStream (aStream);
-        decodeBufferPrefix(ps, bStream);
-        while (true) {
-            int length;
-
-            try {
-                length = decodeLinePrefix(ps, bStream);
-                for (i = 0; (i+bytesPerAtom()) < length; i += bytesPerAtom()) {
-                    decodeAtom(ps, bStream, bytesPerAtom());
-                    totalBytes += bytesPerAtom();
-                }
-                if ((i + bytesPerAtom()) == length) {
-                    decodeAtom(ps, bStream, bytesPerAtom());
-                    totalBytes += bytesPerAtom();
-                } else {
-                    decodeAtom(ps, bStream, length - i);
-                    totalBytes += (length - i);
-                }
-                decodeLineSuffix(ps, bStream);
-            } catch (CEStreamExhausted e) {
-                break;
-            }
-        }
-        decodeBufferSuffix(ps, bStream);
-    }
-
-    /**
-     * Alternate decode interface that takes a String containing the encoded
-     * buffer and returns a byte array containing the data.
-     * @exception CEFormatException An error has occurred while decoding
-     */
-    public byte[] decodeBuffer(String inputString) throws IOException {
-        byte inputBuffer[] = inputString.getBytes("ISO-8859-1");
-        ByteArrayInputStream inStream = new ByteArrayInputStream(inputBuffer);
-        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-        decodeBuffer(inStream, outStream);
-        return outStream.toByteArray();
-    }
-
-    /**
-     * Decode the contents of the inputstream into a buffer.
-     */
-    public byte[] decodeBuffer(InputStream in) throws IOException {
-        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-        decodeBuffer(in, outStream);
-        return outStream.toByteArray();
-    }
-
-    /**
-     * Decode the contents of the String into a ByteBuffer.
-     */
-    public ByteBuffer decodeBufferToByteBuffer(String inputString)
-        throws IOException {
-        return ByteBuffer.wrap(decodeBuffer(inputString));
-    }
-
-    /**
-     * Decode the contents of the inputStream into a ByteBuffer.
-     */
-    public ByteBuffer decodeBufferToByteBuffer(InputStream in)
-        throws IOException {
-        return ByteBuffer.wrap(decodeBuffer(in));
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/CharacterEncoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
-import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-
-/**
- * This class defines the encoding half of character encoders.
- * A character encoder is an algorithim for transforming 8 bit binary
- * data into text (generally 7 bit ASCII or 8 bit ISO-Latin-1 text)
- * for transmition over text channels such as e-mail and network news.
- *
- * The character encoders have been structured around a central theme
- * that, in general, the encoded text has the form:
- *
- * <pre>
- *      [Buffer Prefix]
- *      [Line Prefix][encoded data atoms][Line Suffix]
- *      [Buffer Suffix]
- * </pre>
- *
- * In the CharacterEncoder and CharacterDecoder classes, one complete
- * chunk of data is referred to as a <i>buffer</i>. Encoded buffers
- * are all text, and decoded buffers (sometimes just referred to as
- * buffers) are binary octets.
- *
- * To create a custom encoder, you must, at a minimum,  overide three
- * abstract methods in this class.
- * <DL>
- * <DD>bytesPerAtom which tells the encoder how many bytes to
- * send to encodeAtom
- * <DD>encodeAtom which encodes the bytes sent to it as text.
- * <DD>bytesPerLine which tells the encoder the maximum number of
- * bytes per line.
- * </DL>
- *
- * Several useful encoders have already been written and are
- * referenced in the See Also list below.
- *
- * @author      Chuck McManis
- * @see         CharacterDecoder
- * @see         UCEncoder
- * @see         UUEncoder
- * @see         BASE64Encoder
- */
-public abstract class CharacterEncoder {
-
-    /** Stream that understands "printing" */
-    protected PrintStream pStream;
-
-    /** Return the number of bytes per atom of encoding */
-    protected abstract int bytesPerAtom();
-
-    /** Return the number of bytes that can be encoded per line */
-    protected abstract int bytesPerLine();
-
-    /**
-     * Encode the prefix for the entire buffer. By default is simply
-     * opens the PrintStream for use by the other functions.
-     */
-    protected void encodeBufferPrefix(OutputStream aStream) throws IOException {
-        pStream = new PrintStream(aStream);
-    }
-
-    /**
-     * Encode the suffix for the entire buffer.
-     */
-    protected void encodeBufferSuffix(OutputStream aStream) throws IOException {
-    }
-
-    /**
-     * Encode the prefix that starts every output line.
-     */
-    protected void encodeLinePrefix(OutputStream aStream, int aLength)
-    throws IOException {
-    }
-
-    /**
-     * Encode the suffix that ends every output line. By default
-     * this method just prints a newline into the output stream.
-     */
-    protected void encodeLineSuffix(OutputStream aStream) throws IOException {
-        pStream.println();
-    }
-
-    /** Encode one "atom" of information into characters. */
-    protected abstract void encodeAtom(OutputStream aStream, byte someBytes[],
-                int anOffset, int aLength) throws IOException;
-
-    /**
-     * This method works around the bizarre semantics of BufferedInputStream's
-     * read method.
-     */
-    protected int readFully(InputStream in, byte buffer[])
-        throws java.io.IOException {
-        for (int i = 0; i < buffer.length; i++) {
-            int q = in.read();
-            if (q == -1)
-                return i;
-            buffer[i] = (byte)q;
-        }
-        return buffer.length;
-    }
-
-    /**
-     * Encode bytes from the input stream, and write them as text characters
-     * to the output stream. This method will run until it exhausts the
-     * input stream, but does not print the line suffix for a final
-     * line that is shorter than bytesPerLine().
-     */
-    public void encode(InputStream inStream, OutputStream outStream)
-        throws IOException {
-        int     j;
-        int     numBytes;
-        byte    tmpbuffer[] = new byte[bytesPerLine()];
-
-        encodeBufferPrefix(outStream);
-
-        while (true) {
-            numBytes = readFully(inStream, tmpbuffer);
-            if (numBytes == 0) {
-                break;
-            }
-            encodeLinePrefix(outStream, numBytes);
-            for (j = 0; j < numBytes; j += bytesPerAtom()) {
-
-                if ((j + bytesPerAtom()) <= numBytes) {
-                    encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
-                } else {
-                    encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
-                }
-            }
-            if (numBytes < bytesPerLine()) {
-                break;
-            } else {
-                encodeLineSuffix(outStream);
-            }
-        }
-        encodeBufferSuffix(outStream);
-    }
-
-    /**
-     * Encode the buffer in <i>aBuffer</i> and write the encoded
-     * result to the OutputStream <i>aStream</i>.
-     */
-    public void encode(byte aBuffer[], OutputStream aStream)
-    throws IOException {
-        ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
-        encode(inStream, aStream);
-    }
-
-    /**
-     * A 'streamless' version of encode that simply takes a buffer of
-     * bytes and returns a string containing the encoded buffer.
-     */
-    public String encode(byte aBuffer[]) {
-        ByteArrayOutputStream   outStream = new ByteArrayOutputStream();
-        ByteArrayInputStream    inStream = new ByteArrayInputStream(aBuffer);
-        String retVal = null;
-        try {
-            encode(inStream, outStream);
-            // explicit ascii->unicode conversion
-            retVal = outStream.toString("ISO-8859-1");
-        } catch (Exception IOException) {
-            // This should never happen.
-            throw new Error("CharacterEncoder.encode internal error");
-        }
-        return (retVal);
-    }
-
-    /**
-     * Return a byte array from the remaining bytes in this ByteBuffer.
-     * <P>
-     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
-     * <P>
-     * To avoid an extra copy, the implementation will attempt to return the
-     * byte array backing the ByteBuffer.  If this is not possible, a
-     * new byte array will be created.
-     */
-    private byte [] getBytes(ByteBuffer bb) {
-        /*
-         * This should never return a BufferOverflowException, as we're
-         * careful to allocate just the right amount.
-         */
-        byte [] buf = null;
-
-        /*
-         * If it has a usable backing byte buffer, use it.  Use only
-         * if the array exactly represents the current ByteBuffer.
-         */
-        if (bb.hasArray()) {
-            byte [] tmp = bb.array();
-            if ((tmp.length == bb.capacity()) &&
-                    (tmp.length == bb.remaining())) {
-                buf = tmp;
-                bb.position(bb.limit());
-            }
-        }
-
-        if (buf == null) {
-            /*
-             * This class doesn't have a concept of encode(buf, len, off),
-             * so if we have a partial buffer, we must reallocate
-             * space.
-             */
-            buf = new byte[bb.remaining()];
-
-            /*
-             * position() automatically updated
-             */
-            bb.get(buf);
-        }
-
-        return buf;
-    }
-
-    /**
-     * Encode the <i>aBuffer</i> ByteBuffer and write the encoded
-     * result to the OutputStream <i>aStream</i>.
-     * <P>
-     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
-     */
-    public void encode(ByteBuffer aBuffer, OutputStream aStream)
-        throws IOException {
-        byte [] buf = getBytes(aBuffer);
-        encode(buf, aStream);
-    }
-
-    /**
-     * A 'streamless' version of encode that simply takes a ByteBuffer
-     * and returns a string containing the encoded buffer.
-     * <P>
-     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
-     */
-    public String encode(ByteBuffer aBuffer) {
-        byte [] buf = getBytes(aBuffer);
-        return encode(buf);
-    }
-
-    /**
-     * Encode bytes from the input stream, and write them as text characters
-     * to the output stream. This method will run until it exhausts the
-     * input stream. It differs from encode in that it will add the
-     * line at the end of a final line that is shorter than bytesPerLine().
-     */
-    public void encodeBuffer(InputStream inStream, OutputStream outStream)
-        throws IOException {
-        int     j;
-        int     numBytes;
-        byte    tmpbuffer[] = new byte[bytesPerLine()];
-
-        encodeBufferPrefix(outStream);
-
-        while (true) {
-            numBytes = readFully(inStream, tmpbuffer);
-            if (numBytes == 0) {
-                break;
-            }
-            encodeLinePrefix(outStream, numBytes);
-            for (j = 0; j < numBytes; j += bytesPerAtom()) {
-                if ((j + bytesPerAtom()) <= numBytes) {
-                    encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
-                } else {
-                    encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
-                }
-            }
-            encodeLineSuffix(outStream);
-            if (numBytes < bytesPerLine()) {
-                break;
-            }
-        }
-        encodeBufferSuffix(outStream);
-    }
-
-    /**
-     * Encode the buffer in <i>aBuffer</i> and write the encoded
-     * result to the OutputStream <i>aStream</i>.
-     */
-    public void encodeBuffer(byte aBuffer[], OutputStream aStream)
-    throws IOException {
-        ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
-        encodeBuffer(inStream, aStream);
-    }
-
-    /**
-     * A 'streamless' version of encode that simply takes a buffer of
-     * bytes and returns a string containing the encoded buffer.
-     */
-    public String encodeBuffer(byte aBuffer[]) {
-        ByteArrayOutputStream   outStream = new ByteArrayOutputStream();
-        ByteArrayInputStream    inStream = new ByteArrayInputStream(aBuffer);
-        try {
-            encodeBuffer(inStream, outStream);
-        } catch (Exception IOException) {
-            // This should never happen.
-            throw new Error("CharacterEncoder.encodeBuffer internal error");
-        }
-        return (outStream.toString());
-    }
-
-    /**
-     * Encode the <i>aBuffer</i> ByteBuffer and write the encoded
-     * result to the OutputStream <i>aStream</i>.
-     * <P>
-     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
-     */
-    public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
-        throws IOException {
-        byte [] buf = getBytes(aBuffer);
-        encodeBuffer(buf, aStream);
-    }
-
-    /**
-     * A 'streamless' version of encode that simply takes a ByteBuffer
-     * and returns a string containing the encoded buffer.
-     * <P>
-     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
-     */
-    public String encodeBuffer(ByteBuffer aBuffer) {
-        byte [] buf = getBytes(aBuffer);
-        return encodeBuffer(buf);
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/misc/GC.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/GC.java	Tue Dec 22 13:41:12 2015 -0800
@@ -82,7 +82,7 @@
      */
     public static native long maxObjectInspectionAge();
 
-    private static class Daemon extends ManagedLocalsThread {
+    private static class Daemon extends Thread {
 
         public void run() {
             for (;;) {
@@ -122,7 +122,7 @@
         }
 
         private Daemon(ThreadGroup tg) {
-            super(tg, "GC Daemon");
+            super(tg, null, "GC Daemon", 0L, false);
         }
 
         /* Create a new daemon thread in the root thread group */
--- a/jdk/src/java.base/share/classes/sun/misc/HexDumpEncoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.misc;
-import java.io.PrintStream;
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * This class encodes a buffer into the classic: "Hexadecimal Dump" format of
- * the past. It is useful for analyzing the contents of binary buffers.
- * The format produced is as follows:
- * <pre>
- * xxxx: 00 11 22 33 44 55 66 77   88 99 aa bb cc dd ee ff ................
- * </pre>
- * Where xxxx is the offset into the buffer in 16 byte chunks, followed
- * by ascii coded hexadecimal bytes followed by the ASCII representation of
- * the bytes or '.' if they are not valid bytes.
- *
- * @author      Chuck McManis
- */
-
-public class HexDumpEncoder extends CharacterEncoder {
-
-    private int offset;
-    private int thisLineLength;
-    private int currentByte;
-    private byte thisLine[] = new byte[16];
-
-    static void hexDigit(PrintStream p, byte x) {
-        char c;
-
-        c = (char) ((x >> 4) & 0xf);
-        if (c > 9)
-            c = (char) ((c-10) + 'A');
-        else
-            c = (char)(c + '0');
-        p.write(c);
-        c = (char) (x & 0xf);
-        if (c > 9)
-            c = (char)((c-10) + 'A');
-        else
-            c = (char)(c + '0');
-        p.write(c);
-    }
-
-    protected int bytesPerAtom() {
-        return (1);
-    }
-
-    protected int bytesPerLine() {
-        return (16);
-    }
-
-    protected void encodeBufferPrefix(OutputStream o) throws IOException {
-        offset = 0;
-        super.encodeBufferPrefix(o);
-    }
-
-    protected void encodeLinePrefix(OutputStream o, int len) throws IOException {
-        hexDigit(pStream, (byte)((offset >>> 8) & 0xff));
-        hexDigit(pStream, (byte)(offset & 0xff));
-        pStream.print(": ");
-        currentByte = 0;
-        thisLineLength = len;
-    }
-
-    protected void encodeAtom(OutputStream o, byte buf[], int off, int len) throws IOException {
-        thisLine[currentByte] = buf[off];
-        hexDigit(pStream, buf[off]);
-        pStream.print(" ");
-        currentByte++;
-        if (currentByte == 8)
-            pStream.print("  ");
-    }
-
-    protected void encodeLineSuffix(OutputStream o) throws IOException {
-        if (thisLineLength < 16) {
-            for (int i = thisLineLength; i < 16; i++) {
-                pStream.print("   ");
-                if (i == 7)
-                    pStream.print("  ");
-            }
-        }
-        pStream.print(" ");
-        for (int i = 0; i < thisLineLength; i++) {
-            if ((thisLine[i] < ' ') || (thisLine[i] > 'z')) {
-                pStream.print(".");
-            } else {
-                pStream.write(thisLine[i]);
-            }
-        }
-        pStream.println();
-        offset += thisLineLength;
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java	Tue Dec 22 13:41:12 2015 -0800
@@ -35,8 +35,10 @@
  * A thread that has no permissions, is not a member of any user-defined
  * ThreadGroup and supports the ability to erase ThreadLocals.
  */
-public final class InnocuousThread extends ManagedLocalsThread {
+public final class InnocuousThread extends Thread {
     private static final jdk.internal.misc.Unsafe UNSAFE;
+    private static final long THREAD_LOCALS;
+    private static final long INHERITABLE_THREAD_LOCALS;
     private static final ThreadGroup INNOCUOUSTHREADGROUP;
     private static final AccessControlContext ACC;
     private static final long INHERITEDACCESSCONTROLCONTEXT;
@@ -54,7 +56,7 @@
     }
 
     public InnocuousThread(ThreadGroup group, Runnable target, String name) {
-        super(group, target, name);
+        super(group, target, name, 0L, false);
         UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
         UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader());
     }
@@ -73,6 +75,14 @@
             throw new SecurityException("setContextClassLoader");
     }
 
+    /**
+     * Drops all thread locals (and inherited thread locals).
+     */
+    public final void eraseThreadLocals() {
+        UNSAFE.putObject(this, THREAD_LOCALS, null);
+        UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
+    }
+
     // ensure run method is run only once
     private volatile boolean hasRun;
 
@@ -96,6 +106,10 @@
             Class<?> tk = Thread.class;
             Class<?> gk = ThreadGroup.class;
 
+            THREAD_LOCALS = UNSAFE.objectFieldOffset
+                    (tk.getDeclaredField("threadLocals"));
+            INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
+                    (tk.getDeclaredField("inheritableThreadLocals"));
             INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
                 (tk.getDeclaredField("inheritedAccessControlContext"));
             CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
--- a/jdk/src/java.base/share/classes/sun/misc/ProxyGenerator.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2031 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import sun.security.action.GetBooleanAction;
-
-/**
- * ProxyGenerator contains the code to generate a dynamic proxy class
- * for the java.lang.reflect.Proxy API.
- *
- * The external interfaces to ProxyGenerator is the static
- * "generateProxyClass" method.
- *
- * @author      Peter Jones
- * @since       1.3
- */
-public class ProxyGenerator {
-    /*
-     * In the comments below, "JVMS" refers to The Java Virtual Machine
-     * Specification Second Edition and "JLS" refers to the original
-     * version of The Java Language Specification, unless otherwise
-     * specified.
-     */
-
-    /* generate 1.5-era class file version */
-    private static final int CLASSFILE_MAJOR_VERSION = 49;
-    private static final int CLASSFILE_MINOR_VERSION = 0;
-
-    /*
-     * beginning of constants copied from
-     * sun.tools.java.RuntimeConstants (which no longer exists):
-     */
-
-    /* constant pool tags */
-    private static final int CONSTANT_UTF8              = 1;
-    private static final int CONSTANT_UNICODE           = 2;
-    private static final int CONSTANT_INTEGER           = 3;
-    private static final int CONSTANT_FLOAT             = 4;
-    private static final int CONSTANT_LONG              = 5;
-    private static final int CONSTANT_DOUBLE            = 6;
-    private static final int CONSTANT_CLASS             = 7;
-    private static final int CONSTANT_STRING            = 8;
-    private static final int CONSTANT_FIELD             = 9;
-    private static final int CONSTANT_METHOD            = 10;
-    private static final int CONSTANT_INTERFACEMETHOD   = 11;
-    private static final int CONSTANT_NAMEANDTYPE       = 12;
-
-    /* access and modifier flags */
-    private static final int ACC_PUBLIC                 = 0x00000001;
-    private static final int ACC_PRIVATE                = 0x00000002;
-//  private static final int ACC_PROTECTED              = 0x00000004;
-    private static final int ACC_STATIC                 = 0x00000008;
-    private static final int ACC_FINAL                  = 0x00000010;
-//  private static final int ACC_SYNCHRONIZED           = 0x00000020;
-//  private static final int ACC_VOLATILE               = 0x00000040;
-//  private static final int ACC_TRANSIENT              = 0x00000080;
-//  private static final int ACC_NATIVE                 = 0x00000100;
-//  private static final int ACC_INTERFACE              = 0x00000200;
-//  private static final int ACC_ABSTRACT               = 0x00000400;
-    private static final int ACC_SUPER                  = 0x00000020;
-//  private static final int ACC_STRICT                 = 0x00000800;
-
-    /* opcodes */
-//  private static final int opc_nop                    = 0;
-    private static final int opc_aconst_null            = 1;
-//  private static final int opc_iconst_m1              = 2;
-    private static final int opc_iconst_0               = 3;
-//  private static final int opc_iconst_1               = 4;
-//  private static final int opc_iconst_2               = 5;
-//  private static final int opc_iconst_3               = 6;
-//  private static final int opc_iconst_4               = 7;
-//  private static final int opc_iconst_5               = 8;
-//  private static final int opc_lconst_0               = 9;
-//  private static final int opc_lconst_1               = 10;
-//  private static final int opc_fconst_0               = 11;
-//  private static final int opc_fconst_1               = 12;
-//  private static final int opc_fconst_2               = 13;
-//  private static final int opc_dconst_0               = 14;
-//  private static final int opc_dconst_1               = 15;
-    private static final int opc_bipush                 = 16;
-    private static final int opc_sipush                 = 17;
-    private static final int opc_ldc                    = 18;
-    private static final int opc_ldc_w                  = 19;
-//  private static final int opc_ldc2_w                 = 20;
-    private static final int opc_iload                  = 21;
-    private static final int opc_lload                  = 22;
-    private static final int opc_fload                  = 23;
-    private static final int opc_dload                  = 24;
-    private static final int opc_aload                  = 25;
-    private static final int opc_iload_0                = 26;
-//  private static final int opc_iload_1                = 27;
-//  private static final int opc_iload_2                = 28;
-//  private static final int opc_iload_3                = 29;
-    private static final int opc_lload_0                = 30;
-//  private static final int opc_lload_1                = 31;
-//  private static final int opc_lload_2                = 32;
-//  private static final int opc_lload_3                = 33;
-    private static final int opc_fload_0                = 34;
-//  private static final int opc_fload_1                = 35;
-//  private static final int opc_fload_2                = 36;
-//  private static final int opc_fload_3                = 37;
-    private static final int opc_dload_0                = 38;
-//  private static final int opc_dload_1                = 39;
-//  private static final int opc_dload_2                = 40;
-//  private static final int opc_dload_3                = 41;
-    private static final int opc_aload_0                = 42;
-//  private static final int opc_aload_1                = 43;
-//  private static final int opc_aload_2                = 44;
-//  private static final int opc_aload_3                = 45;
-//  private static final int opc_iaload                 = 46;
-//  private static final int opc_laload                 = 47;
-//  private static final int opc_faload                 = 48;
-//  private static final int opc_daload                 = 49;
-//  private static final int opc_aaload                 = 50;
-//  private static final int opc_baload                 = 51;
-//  private static final int opc_caload                 = 52;
-//  private static final int opc_saload                 = 53;
-//  private static final int opc_istore                 = 54;
-//  private static final int opc_lstore                 = 55;
-//  private static final int opc_fstore                 = 56;
-//  private static final int opc_dstore                 = 57;
-    private static final int opc_astore                 = 58;
-//  private static final int opc_istore_0               = 59;
-//  private static final int opc_istore_1               = 60;
-//  private static final int opc_istore_2               = 61;
-//  private static final int opc_istore_3               = 62;
-//  private static final int opc_lstore_0               = 63;
-//  private static final int opc_lstore_1               = 64;
-//  private static final int opc_lstore_2               = 65;
-//  private static final int opc_lstore_3               = 66;
-//  private static final int opc_fstore_0               = 67;
-//  private static final int opc_fstore_1               = 68;
-//  private static final int opc_fstore_2               = 69;
-//  private static final int opc_fstore_3               = 70;
-//  private static final int opc_dstore_0               = 71;
-//  private static final int opc_dstore_1               = 72;
-//  private static final int opc_dstore_2               = 73;
-//  private static final int opc_dstore_3               = 74;
-    private static final int opc_astore_0               = 75;
-//  private static final int opc_astore_1               = 76;
-//  private static final int opc_astore_2               = 77;
-//  private static final int opc_astore_3               = 78;
-//  private static final int opc_iastore                = 79;
-//  private static final int opc_lastore                = 80;
-//  private static final int opc_fastore                = 81;
-//  private static final int opc_dastore                = 82;
-    private static final int opc_aastore                = 83;
-//  private static final int opc_bastore                = 84;
-//  private static final int opc_castore                = 85;
-//  private static final int opc_sastore                = 86;
-    private static final int opc_pop                    = 87;
-//  private static final int opc_pop2                   = 88;
-    private static final int opc_dup                    = 89;
-//  private static final int opc_dup_x1                 = 90;
-//  private static final int opc_dup_x2                 = 91;
-//  private static final int opc_dup2                   = 92;
-//  private static final int opc_dup2_x1                = 93;
-//  private static final int opc_dup2_x2                = 94;
-//  private static final int opc_swap                   = 95;
-//  private static final int opc_iadd                   = 96;
-//  private static final int opc_ladd                   = 97;
-//  private static final int opc_fadd                   = 98;
-//  private static final int opc_dadd                   = 99;
-//  private static final int opc_isub                   = 100;
-//  private static final int opc_lsub                   = 101;
-//  private static final int opc_fsub                   = 102;
-//  private static final int opc_dsub                   = 103;
-//  private static final int opc_imul                   = 104;
-//  private static final int opc_lmul                   = 105;
-//  private static final int opc_fmul                   = 106;
-//  private static final int opc_dmul                   = 107;
-//  private static final int opc_idiv                   = 108;
-//  private static final int opc_ldiv                   = 109;
-//  private static final int opc_fdiv                   = 110;
-//  private static final int opc_ddiv                   = 111;
-//  private static final int opc_irem                   = 112;
-//  private static final int opc_lrem                   = 113;
-//  private static final int opc_frem                   = 114;
-//  private static final int opc_drem                   = 115;
-//  private static final int opc_ineg                   = 116;
-//  private static final int opc_lneg                   = 117;
-//  private static final int opc_fneg                   = 118;
-//  private static final int opc_dneg                   = 119;
-//  private static final int opc_ishl                   = 120;
-//  private static final int opc_lshl                   = 121;
-//  private static final int opc_ishr                   = 122;
-//  private static final int opc_lshr                   = 123;
-//  private static final int opc_iushr                  = 124;
-//  private static final int opc_lushr                  = 125;
-//  private static final int opc_iand                   = 126;
-//  private static final int opc_land                   = 127;
-//  private static final int opc_ior                    = 128;
-//  private static final int opc_lor                    = 129;
-//  private static final int opc_ixor                   = 130;
-//  private static final int opc_lxor                   = 131;
-//  private static final int opc_iinc                   = 132;
-//  private static final int opc_i2l                    = 133;
-//  private static final int opc_i2f                    = 134;
-//  private static final int opc_i2d                    = 135;
-//  private static final int opc_l2i                    = 136;
-//  private static final int opc_l2f                    = 137;
-//  private static final int opc_l2d                    = 138;
-//  private static final int opc_f2i                    = 139;
-//  private static final int opc_f2l                    = 140;
-//  private static final int opc_f2d                    = 141;
-//  private static final int opc_d2i                    = 142;
-//  private static final int opc_d2l                    = 143;
-//  private static final int opc_d2f                    = 144;
-//  private static final int opc_i2b                    = 145;
-//  private static final int opc_i2c                    = 146;
-//  private static final int opc_i2s                    = 147;
-//  private static final int opc_lcmp                   = 148;
-//  private static final int opc_fcmpl                  = 149;
-//  private static final int opc_fcmpg                  = 150;
-//  private static final int opc_dcmpl                  = 151;
-//  private static final int opc_dcmpg                  = 152;
-//  private static final int opc_ifeq                   = 153;
-//  private static final int opc_ifne                   = 154;
-//  private static final int opc_iflt                   = 155;
-//  private static final int opc_ifge                   = 156;
-//  private static final int opc_ifgt                   = 157;
-//  private static final int opc_ifle                   = 158;
-//  private static final int opc_if_icmpeq              = 159;
-//  private static final int opc_if_icmpne              = 160;
-//  private static final int opc_if_icmplt              = 161;
-//  private static final int opc_if_icmpge              = 162;
-//  private static final int opc_if_icmpgt              = 163;
-//  private static final int opc_if_icmple              = 164;
-//  private static final int opc_if_acmpeq              = 165;
-//  private static final int opc_if_acmpne              = 166;
-//  private static final int opc_goto                   = 167;
-//  private static final int opc_jsr                    = 168;
-//  private static final int opc_ret                    = 169;
-//  private static final int opc_tableswitch            = 170;
-//  private static final int opc_lookupswitch           = 171;
-    private static final int opc_ireturn                = 172;
-    private static final int opc_lreturn                = 173;
-    private static final int opc_freturn                = 174;
-    private static final int opc_dreturn                = 175;
-    private static final int opc_areturn                = 176;
-    private static final int opc_return                 = 177;
-    private static final int opc_getstatic              = 178;
-    private static final int opc_putstatic              = 179;
-    private static final int opc_getfield               = 180;
-//  private static final int opc_putfield               = 181;
-    private static final int opc_invokevirtual          = 182;
-    private static final int opc_invokespecial          = 183;
-    private static final int opc_invokestatic           = 184;
-    private static final int opc_invokeinterface        = 185;
-    private static final int opc_new                    = 187;
-//  private static final int opc_newarray               = 188;
-    private static final int opc_anewarray              = 189;
-//  private static final int opc_arraylength            = 190;
-    private static final int opc_athrow                 = 191;
-    private static final int opc_checkcast              = 192;
-//  private static final int opc_instanceof             = 193;
-//  private static final int opc_monitorenter           = 194;
-//  private static final int opc_monitorexit            = 195;
-    private static final int opc_wide                   = 196;
-//  private static final int opc_multianewarray         = 197;
-//  private static final int opc_ifnull                 = 198;
-//  private static final int opc_ifnonnull              = 199;
-//  private static final int opc_goto_w                 = 200;
-//  private static final int opc_jsr_w                  = 201;
-
-    // end of constants copied from sun.tools.java.RuntimeConstants
-
-    /** name of the superclass of proxy classes */
-    private static final String superclassName = "java/lang/reflect/Proxy";
-
-    /** name of field for storing a proxy instance's invocation handler */
-    private static final String handlerFieldName = "h";
-
-    /** debugging flag for saving generated class files */
-    private static final boolean saveGeneratedFiles =
-        java.security.AccessController.doPrivileged(
-            new GetBooleanAction(
-                "sun.misc.ProxyGenerator.saveGeneratedFiles")).booleanValue();
-
-    /**
-     * Generate a public proxy class given a name and a list of proxy interfaces.
-     */
-    public static byte[] generateProxyClass(final String name,
-                                            Class<?>[] interfaces) {
-        return generateProxyClass(name, interfaces, (ACC_PUBLIC | ACC_FINAL | ACC_SUPER));
-    }
-
-    /**
-     * Generate a proxy class given a name and a list of proxy interfaces.
-     *
-     * @param name        the class name of the proxy class
-     * @param interfaces  proxy interfaces
-     * @param accessFlags access flags of the proxy class
-    */
-    public static byte[] generateProxyClass(final String name,
-                                            Class<?>[] interfaces,
-                                            int accessFlags)
-    {
-        ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
-        final byte[] classFile = gen.generateClassFile();
-
-        if (saveGeneratedFiles) {
-            java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<Void>() {
-                public Void run() {
-                    try {
-                        int i = name.lastIndexOf('.');
-                        Path path;
-                        if (i > 0) {
-                            Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar));
-                            Files.createDirectories(dir);
-                            path = dir.resolve(name.substring(i+1, name.length()) + ".class");
-                        } else {
-                            path = Paths.get(name + ".class");
-                        }
-                        Files.write(path, classFile);
-                        return null;
-                    } catch (IOException e) {
-                        throw new InternalError(
-                            "I/O exception saving generated file: " + e);
-                    }
-                }
-            });
-        }
-
-        return classFile;
-    }
-
-    /* preloaded Method objects for methods in java.lang.Object */
-    private static Method hashCodeMethod;
-    private static Method equalsMethod;
-    private static Method toStringMethod;
-    static {
-        try {
-            hashCodeMethod = Object.class.getMethod("hashCode");
-            equalsMethod =
-                Object.class.getMethod("equals", new Class<?>[] { Object.class });
-            toStringMethod = Object.class.getMethod("toString");
-        } catch (NoSuchMethodException e) {
-            throw new NoSuchMethodError(e.getMessage());
-        }
-    }
-
-    /** name of proxy class */
-    private String className;
-
-    /** proxy interfaces */
-    private Class<?>[] interfaces;
-
-    /** proxy class access flags */
-    private int accessFlags;
-
-    /** constant pool of class being generated */
-    private ConstantPool cp = new ConstantPool();
-
-    /** FieldInfo struct for each field of generated class */
-    private List<FieldInfo> fields = new ArrayList<>();
-
-    /** MethodInfo struct for each method of generated class */
-    private List<MethodInfo> methods = new ArrayList<>();
-
-    /**
-     * maps method signature string to list of ProxyMethod objects for
-     * proxy methods with that signature
-     */
-    private Map<String, List<ProxyMethod>> proxyMethods = new HashMap<>();
-
-    /** count of ProxyMethod objects added to proxyMethods */
-    private int proxyMethodCount = 0;
-
-    /**
-     * Construct a ProxyGenerator to generate a proxy class with the
-     * specified name and for the given interfaces.
-     *
-     * A ProxyGenerator object contains the state for the ongoing
-     * generation of a particular proxy class.
-     */
-    private ProxyGenerator(String className, Class<?>[] interfaces, int accessFlags) {
-        this.className = className;
-        this.interfaces = interfaces;
-        this.accessFlags = accessFlags;
-    }
-
-    /**
-     * Generate a class file for the proxy class.  This method drives the
-     * class file generation process.
-     */
-    private byte[] generateClassFile() {
-
-        /* ============================================================
-         * Step 1: Assemble ProxyMethod objects for all methods to
-         * generate proxy dispatching code for.
-         */
-
-        /*
-         * Record that proxy methods are needed for the hashCode, equals,
-         * and toString methods of java.lang.Object.  This is done before
-         * the methods from the proxy interfaces so that the methods from
-         * java.lang.Object take precedence over duplicate methods in the
-         * proxy interfaces.
-         */
-        addProxyMethod(hashCodeMethod, Object.class);
-        addProxyMethod(equalsMethod, Object.class);
-        addProxyMethod(toStringMethod, Object.class);
-
-        /*
-         * Now record all of the methods from the proxy interfaces, giving
-         * earlier interfaces precedence over later ones with duplicate
-         * methods.
-         */
-        for (Class<?> intf : interfaces) {
-            for (Method m : intf.getMethods()) {
-                addProxyMethod(m, intf);
-            }
-        }
-
-        /*
-         * For each set of proxy methods with the same signature,
-         * verify that the methods' return types are compatible.
-         */
-        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
-            checkReturnTypes(sigmethods);
-        }
-
-        /* ============================================================
-         * Step 2: Assemble FieldInfo and MethodInfo structs for all of
-         * fields and methods in the class we are generating.
-         */
-        try {
-            methods.add(generateConstructor());
-
-            for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
-                for (ProxyMethod pm : sigmethods) {
-
-                    // add static field for method's Method object
-                    fields.add(new FieldInfo(pm.methodFieldName,
-                        "Ljava/lang/reflect/Method;",
-                         ACC_PRIVATE | ACC_STATIC));
-
-                    // generate code for proxy method and add it
-                    methods.add(pm.generateMethod());
-                }
-            }
-
-            methods.add(generateStaticInitializer());
-
-        } catch (IOException e) {
-            throw new InternalError("unexpected I/O Exception", e);
-        }
-
-        if (methods.size() > 65535) {
-            throw new IllegalArgumentException("method limit exceeded");
-        }
-        if (fields.size() > 65535) {
-            throw new IllegalArgumentException("field limit exceeded");
-        }
-
-        /* ============================================================
-         * Step 3: Write the final class file.
-         */
-
-        /*
-         * Make sure that constant pool indexes are reserved for the
-         * following items before starting to write the final class file.
-         */
-        cp.getClass(dotToSlash(className));
-        cp.getClass(superclassName);
-        for (Class<?> intf: interfaces) {
-            cp.getClass(dotToSlash(intf.getName()));
-        }
-
-        /*
-         * Disallow new constant pool additions beyond this point, since
-         * we are about to write the final constant pool table.
-         */
-        cp.setReadOnly();
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        DataOutputStream dout = new DataOutputStream(bout);
-
-        try {
-            /*
-             * Write all the items of the "ClassFile" structure.
-             * See JVMS section 4.1.
-             */
-                                        // u4 magic;
-            dout.writeInt(0xCAFEBABE);
-                                        // u2 minor_version;
-            dout.writeShort(CLASSFILE_MINOR_VERSION);
-                                        // u2 major_version;
-            dout.writeShort(CLASSFILE_MAJOR_VERSION);
-
-            cp.write(dout);             // (write constant pool)
-
-                                        // u2 access_flags;
-            dout.writeShort(accessFlags);
-                                        // u2 this_class;
-            dout.writeShort(cp.getClass(dotToSlash(className)));
-                                        // u2 super_class;
-            dout.writeShort(cp.getClass(superclassName));
-
-                                        // u2 interfaces_count;
-            dout.writeShort(interfaces.length);
-                                        // u2 interfaces[interfaces_count];
-            for (Class<?> intf : interfaces) {
-                dout.writeShort(cp.getClass(
-                    dotToSlash(intf.getName())));
-            }
-
-                                        // u2 fields_count;
-            dout.writeShort(fields.size());
-                                        // field_info fields[fields_count];
-            for (FieldInfo f : fields) {
-                f.write(dout);
-            }
-
-                                        // u2 methods_count;
-            dout.writeShort(methods.size());
-                                        // method_info methods[methods_count];
-            for (MethodInfo m : methods) {
-                m.write(dout);
-            }
-
-                                         // u2 attributes_count;
-            dout.writeShort(0); // (no ClassFile attributes for proxy classes)
-
-        } catch (IOException e) {
-            throw new InternalError("unexpected I/O Exception", e);
-        }
-
-        return bout.toByteArray();
-    }
-
-    /**
-     * Add another method to be proxied, either by creating a new
-     * ProxyMethod object or augmenting an old one for a duplicate
-     * method.
-     *
-     * "fromClass" indicates the proxy interface that the method was
-     * found through, which may be different from (a subinterface of)
-     * the method's "declaring class".  Note that the first Method
-     * object passed for a given name and descriptor identifies the
-     * Method object (and thus the declaring class) that will be
-     * passed to the invocation handler's "invoke" method for a given
-     * set of duplicate methods.
-     */
-    private void addProxyMethod(Method m, Class<?> fromClass) {
-        String name = m.getName();
-        Class<?>[] parameterTypes = m.getParameterTypes();
-        Class<?> returnType = m.getReturnType();
-        Class<?>[] exceptionTypes = m.getExceptionTypes();
-
-        String sig = name + getParameterDescriptors(parameterTypes);
-        List<ProxyMethod> sigmethods = proxyMethods.get(sig);
-        if (sigmethods != null) {
-            for (ProxyMethod pm : sigmethods) {
-                if (returnType == pm.returnType) {
-                    /*
-                     * Found a match: reduce exception types to the
-                     * greatest set of exceptions that can thrown
-                     * compatibly with the throws clauses of both
-                     * overridden methods.
-                     */
-                    List<Class<?>> legalExceptions = new ArrayList<>();
-                    collectCompatibleTypes(
-                        exceptionTypes, pm.exceptionTypes, legalExceptions);
-                    collectCompatibleTypes(
-                        pm.exceptionTypes, exceptionTypes, legalExceptions);
-                    pm.exceptionTypes = new Class<?>[legalExceptions.size()];
-                    pm.exceptionTypes =
-                        legalExceptions.toArray(pm.exceptionTypes);
-                    return;
-                }
-            }
-        } else {
-            sigmethods = new ArrayList<>(3);
-            proxyMethods.put(sig, sigmethods);
-        }
-        sigmethods.add(new ProxyMethod(name, parameterTypes, returnType,
-                                       exceptionTypes, fromClass));
-    }
-
-    /**
-     * For a given set of proxy methods with the same signature, check
-     * that their return types are compatible according to the Proxy
-     * specification.
-     *
-     * Specifically, if there is more than one such method, then all
-     * of the return types must be reference types, and there must be
-     * one return type that is assignable to each of the rest of them.
-     */
-    private static void checkReturnTypes(List<ProxyMethod> methods) {
-        /*
-         * If there is only one method with a given signature, there
-         * cannot be a conflict.  This is the only case in which a
-         * primitive (or void) return type is allowed.
-         */
-        if (methods.size() < 2) {
-            return;
-        }
-
-        /*
-         * List of return types that are not yet known to be
-         * assignable from ("covered" by) any of the others.
-         */
-        LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<>();
-
-    nextNewReturnType:
-        for (ProxyMethod pm : methods) {
-            Class<?> newReturnType = pm.returnType;
-            if (newReturnType.isPrimitive()) {
-                throw new IllegalArgumentException(
-                    "methods with same signature " +
-                    getFriendlyMethodSignature(pm.methodName,
-                                               pm.parameterTypes) +
-                    " but incompatible return types: " +
-                    newReturnType.getName() + " and others");
-            }
-            boolean added = false;
-
-            /*
-             * Compare the new return type to the existing uncovered
-             * return types.
-             */
-            ListIterator<Class<?>> liter = uncoveredReturnTypes.listIterator();
-            while (liter.hasNext()) {
-                Class<?> uncoveredReturnType = liter.next();
-
-                /*
-                 * If an existing uncovered return type is assignable
-                 * to this new one, then we can forget the new one.
-                 */
-                if (newReturnType.isAssignableFrom(uncoveredReturnType)) {
-                    assert !added;
-                    continue nextNewReturnType;
-                }
-
-                /*
-                 * If the new return type is assignable to an existing
-                 * uncovered one, then should replace the existing one
-                 * with the new one (or just forget the existing one,
-                 * if the new one has already be put in the list).
-                 */
-                if (uncoveredReturnType.isAssignableFrom(newReturnType)) {
-                    // (we can assume that each return type is unique)
-                    if (!added) {
-                        liter.set(newReturnType);
-                        added = true;
-                    } else {
-                        liter.remove();
-                    }
-                }
-            }
-
-            /*
-             * If we got through the list of existing uncovered return
-             * types without an assignability relationship, then add
-             * the new return type to the list of uncovered ones.
-             */
-            if (!added) {
-                uncoveredReturnTypes.add(newReturnType);
-            }
-        }
-
-        /*
-         * We shouldn't end up with more than one return type that is
-         * not assignable from any of the others.
-         */
-        if (uncoveredReturnTypes.size() > 1) {
-            ProxyMethod pm = methods.get(0);
-            throw new IllegalArgumentException(
-                "methods with same signature " +
-                getFriendlyMethodSignature(pm.methodName, pm.parameterTypes) +
-                " but incompatible return types: " + uncoveredReturnTypes);
-        }
-    }
-
-    /**
-     * A FieldInfo object contains information about a particular field
-     * in the class being generated.  The class mirrors the data items of
-     * the "field_info" structure of the class file format (see JVMS 4.5).
-     */
-    private class FieldInfo {
-        public int accessFlags;
-        public String name;
-        public String descriptor;
-
-        public FieldInfo(String name, String descriptor, int accessFlags) {
-            this.name = name;
-            this.descriptor = descriptor;
-            this.accessFlags = accessFlags;
-
-            /*
-             * Make sure that constant pool indexes are reserved for the
-             * following items before starting to write the final class file.
-             */
-            cp.getUtf8(name);
-            cp.getUtf8(descriptor);
-        }
-
-        public void write(DataOutputStream out) throws IOException {
-            /*
-             * Write all the items of the "field_info" structure.
-             * See JVMS section 4.5.
-             */
-                                        // u2 access_flags;
-            out.writeShort(accessFlags);
-                                        // u2 name_index;
-            out.writeShort(cp.getUtf8(name));
-                                        // u2 descriptor_index;
-            out.writeShort(cp.getUtf8(descriptor));
-                                        // u2 attributes_count;
-            out.writeShort(0);  // (no field_info attributes for proxy classes)
-        }
-    }
-
-    /**
-     * An ExceptionTableEntry object holds values for the data items of
-     * an entry in the "exception_table" item of the "Code" attribute of
-     * "method_info" structures (see JVMS 4.7.3).
-     */
-    private static class ExceptionTableEntry {
-        public short startPc;
-        public short endPc;
-        public short handlerPc;
-        public short catchType;
-
-        public ExceptionTableEntry(short startPc, short endPc,
-                                   short handlerPc, short catchType)
-        {
-            this.startPc = startPc;
-            this.endPc = endPc;
-            this.handlerPc = handlerPc;
-            this.catchType = catchType;
-        }
-    };
-
-    /**
-     * A MethodInfo object contains information about a particular method
-     * in the class being generated.  This class mirrors the data items of
-     * the "method_info" structure of the class file format (see JVMS 4.6).
-     */
-    private class MethodInfo {
-        public int accessFlags;
-        public String name;
-        public String descriptor;
-        public short maxStack;
-        public short maxLocals;
-        public ByteArrayOutputStream code = new ByteArrayOutputStream();
-        public List<ExceptionTableEntry> exceptionTable =
-            new ArrayList<ExceptionTableEntry>();
-        public short[] declaredExceptions;
-
-        public MethodInfo(String name, String descriptor, int accessFlags) {
-            this.name = name;
-            this.descriptor = descriptor;
-            this.accessFlags = accessFlags;
-
-            /*
-             * Make sure that constant pool indexes are reserved for the
-             * following items before starting to write the final class file.
-             */
-            cp.getUtf8(name);
-            cp.getUtf8(descriptor);
-            cp.getUtf8("Code");
-            cp.getUtf8("Exceptions");
-        }
-
-        public void write(DataOutputStream out) throws IOException {
-            /*
-             * Write all the items of the "method_info" structure.
-             * See JVMS section 4.6.
-             */
-                                        // u2 access_flags;
-            out.writeShort(accessFlags);
-                                        // u2 name_index;
-            out.writeShort(cp.getUtf8(name));
-                                        // u2 descriptor_index;
-            out.writeShort(cp.getUtf8(descriptor));
-                                        // u2 attributes_count;
-            out.writeShort(2);  // (two method_info attributes:)
-
-            // Write "Code" attribute. See JVMS section 4.7.3.
-
-                                        // u2 attribute_name_index;
-            out.writeShort(cp.getUtf8("Code"));
-                                        // u4 attribute_length;
-            out.writeInt(12 + code.size() + 8 * exceptionTable.size());
-                                        // u2 max_stack;
-            out.writeShort(maxStack);
-                                        // u2 max_locals;
-            out.writeShort(maxLocals);
-                                        // u2 code_length;
-            out.writeInt(code.size());
-                                        // u1 code[code_length];
-            code.writeTo(out);
-                                        // u2 exception_table_length;
-            out.writeShort(exceptionTable.size());
-            for (ExceptionTableEntry e : exceptionTable) {
-                                        // u2 start_pc;
-                out.writeShort(e.startPc);
-                                        // u2 end_pc;
-                out.writeShort(e.endPc);
-                                        // u2 handler_pc;
-                out.writeShort(e.handlerPc);
-                                        // u2 catch_type;
-                out.writeShort(e.catchType);
-            }
-                                        // u2 attributes_count;
-            out.writeShort(0);
-
-            // write "Exceptions" attribute.  See JVMS section 4.7.4.
-
-                                        // u2 attribute_name_index;
-            out.writeShort(cp.getUtf8("Exceptions"));
-                                        // u4 attributes_length;
-            out.writeInt(2 + 2 * declaredExceptions.length);
-                                        // u2 number_of_exceptions;
-            out.writeShort(declaredExceptions.length);
-                        // u2 exception_index_table[number_of_exceptions];
-            for (short value : declaredExceptions) {
-                out.writeShort(value);
-            }
-        }
-
-    }
-
-    /**
-     * A ProxyMethod object represents a proxy method in the proxy class
-     * being generated: a method whose implementation will encode and
-     * dispatch invocations to the proxy instance's invocation handler.
-     */
-    private class ProxyMethod {
-
-        public String methodName;
-        public Class<?>[] parameterTypes;
-        public Class<?> returnType;
-        public Class<?>[] exceptionTypes;
-        public Class<?> fromClass;
-        public String methodFieldName;
-
-        private ProxyMethod(String methodName, Class<?>[] parameterTypes,
-                            Class<?> returnType, Class<?>[] exceptionTypes,
-                            Class<?> fromClass)
-        {
-            this.methodName = methodName;
-            this.parameterTypes = parameterTypes;
-            this.returnType = returnType;
-            this.exceptionTypes = exceptionTypes;
-            this.fromClass = fromClass;
-            this.methodFieldName = "m" + proxyMethodCount++;
-        }
-
-        /**
-         * Return a MethodInfo object for this method, including generating
-         * the code and exception table entry.
-         */
-        private MethodInfo generateMethod() throws IOException {
-            String desc = getMethodDescriptor(parameterTypes, returnType);
-            MethodInfo minfo = new MethodInfo(methodName, desc,
-                ACC_PUBLIC | ACC_FINAL);
-
-            int[] parameterSlot = new int[parameterTypes.length];
-            int nextSlot = 1;
-            for (int i = 0; i < parameterSlot.length; i++) {
-                parameterSlot[i] = nextSlot;
-                nextSlot += getWordsPerType(parameterTypes[i]);
-            }
-            int localSlot0 = nextSlot;
-            short pc, tryBegin = 0, tryEnd;
-
-            DataOutputStream out = new DataOutputStream(minfo.code);
-
-            code_aload(0, out);
-
-            out.writeByte(opc_getfield);
-            out.writeShort(cp.getFieldRef(
-                superclassName,
-                handlerFieldName, "Ljava/lang/reflect/InvocationHandler;"));
-
-            code_aload(0, out);
-
-            out.writeByte(opc_getstatic);
-            out.writeShort(cp.getFieldRef(
-                dotToSlash(className),
-                methodFieldName, "Ljava/lang/reflect/Method;"));
-
-            if (parameterTypes.length > 0) {
-
-                code_ipush(parameterTypes.length, out);
-
-                out.writeByte(opc_anewarray);
-                out.writeShort(cp.getClass("java/lang/Object"));
-
-                for (int i = 0; i < parameterTypes.length; i++) {
-
-                    out.writeByte(opc_dup);
-
-                    code_ipush(i, out);
-
-                    codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
-
-                    out.writeByte(opc_aastore);
-                }
-            } else {
-
-                out.writeByte(opc_aconst_null);
-            }
-
-            out.writeByte(opc_invokeinterface);
-            out.writeShort(cp.getInterfaceMethodRef(
-                "java/lang/reflect/InvocationHandler",
-                "invoke",
-                "(Ljava/lang/Object;Ljava/lang/reflect/Method;" +
-                    "[Ljava/lang/Object;)Ljava/lang/Object;"));
-            out.writeByte(4);
-            out.writeByte(0);
-
-            if (returnType == void.class) {
-
-                out.writeByte(opc_pop);
-
-                out.writeByte(opc_return);
-
-            } else {
-
-                codeUnwrapReturnValue(returnType, out);
-            }
-
-            tryEnd = pc = (short) minfo.code.size();
-
-            List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
-            if (catchList.size() > 0) {
-
-                for (Class<?> ex : catchList) {
-                    minfo.exceptionTable.add(new ExceptionTableEntry(
-                        tryBegin, tryEnd, pc,
-                        cp.getClass(dotToSlash(ex.getName()))));
-                }
-
-                out.writeByte(opc_athrow);
-
-                pc = (short) minfo.code.size();
-
-                minfo.exceptionTable.add(new ExceptionTableEntry(
-                    tryBegin, tryEnd, pc, cp.getClass("java/lang/Throwable")));
-
-                code_astore(localSlot0, out);
-
-                out.writeByte(opc_new);
-                out.writeShort(cp.getClass(
-                    "java/lang/reflect/UndeclaredThrowableException"));
-
-                out.writeByte(opc_dup);
-
-                code_aload(localSlot0, out);
-
-                out.writeByte(opc_invokespecial);
-
-                out.writeShort(cp.getMethodRef(
-                    "java/lang/reflect/UndeclaredThrowableException",
-                    "<init>", "(Ljava/lang/Throwable;)V"));
-
-                out.writeByte(opc_athrow);
-            }
-
-            if (minfo.code.size() > 65535) {
-                throw new IllegalArgumentException("code size limit exceeded");
-            }
-
-            minfo.maxStack = 10;
-            minfo.maxLocals = (short) (localSlot0 + 1);
-            minfo.declaredExceptions = new short[exceptionTypes.length];
-            for (int i = 0; i < exceptionTypes.length; i++) {
-                minfo.declaredExceptions[i] = cp.getClass(
-                    dotToSlash(exceptionTypes[i].getName()));
-            }
-
-            return minfo;
-        }
-
-        /**
-         * Generate code for wrapping an argument of the given type
-         * whose value can be found at the specified local variable
-         * index, in order for it to be passed (as an Object) to the
-         * invocation handler's "invoke" method.  The code is written
-         * to the supplied stream.
-         */
-        private void codeWrapArgument(Class<?> type, int slot,
-                                      DataOutputStream out)
-            throws IOException
-        {
-            if (type.isPrimitive()) {
-                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
-
-                if (type == int.class ||
-                    type == boolean.class ||
-                    type == byte.class ||
-                    type == char.class ||
-                    type == short.class)
-                {
-                    code_iload(slot, out);
-                } else if (type == long.class) {
-                    code_lload(slot, out);
-                } else if (type == float.class) {
-                    code_fload(slot, out);
-                } else if (type == double.class) {
-                    code_dload(slot, out);
-                } else {
-                    throw new AssertionError();
-                }
-
-                out.writeByte(opc_invokestatic);
-                out.writeShort(cp.getMethodRef(
-                    prim.wrapperClassName,
-                    "valueOf", prim.wrapperValueOfDesc));
-
-            } else {
-
-                code_aload(slot, out);
-            }
-        }
-
-        /**
-         * Generate code for unwrapping a return value of the given
-         * type from the invocation handler's "invoke" method (as type
-         * Object) to its correct type.  The code is written to the
-         * supplied stream.
-         */
-        private void codeUnwrapReturnValue(Class<?> type, DataOutputStream out)
-            throws IOException
-        {
-            if (type.isPrimitive()) {
-                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
-
-                out.writeByte(opc_checkcast);
-                out.writeShort(cp.getClass(prim.wrapperClassName));
-
-                out.writeByte(opc_invokevirtual);
-                out.writeShort(cp.getMethodRef(
-                    prim.wrapperClassName,
-                    prim.unwrapMethodName, prim.unwrapMethodDesc));
-
-                if (type == int.class ||
-                    type == boolean.class ||
-                    type == byte.class ||
-                    type == char.class ||
-                    type == short.class)
-                {
-                    out.writeByte(opc_ireturn);
-                } else if (type == long.class) {
-                    out.writeByte(opc_lreturn);
-                } else if (type == float.class) {
-                    out.writeByte(opc_freturn);
-                } else if (type == double.class) {
-                    out.writeByte(opc_dreturn);
-                } else {
-                    throw new AssertionError();
-                }
-
-            } else {
-
-                out.writeByte(opc_checkcast);
-                out.writeShort(cp.getClass(dotToSlash(type.getName())));
-
-                out.writeByte(opc_areturn);
-            }
-        }
-
-        /**
-         * Generate code for initializing the static field that stores
-         * the Method object for this proxy method.  The code is written
-         * to the supplied stream.
-         */
-        private void codeFieldInitialization(DataOutputStream out)
-            throws IOException
-        {
-            codeClassForName(fromClass, out);
-
-            code_ldc(cp.getString(methodName), out);
-
-            code_ipush(parameterTypes.length, out);
-
-            out.writeByte(opc_anewarray);
-            out.writeShort(cp.getClass("java/lang/Class"));
-
-            for (int i = 0; i < parameterTypes.length; i++) {
-
-                out.writeByte(opc_dup);
-
-                code_ipush(i, out);
-
-                if (parameterTypes[i].isPrimitive()) {
-                    PrimitiveTypeInfo prim =
-                        PrimitiveTypeInfo.get(parameterTypes[i]);
-
-                    out.writeByte(opc_getstatic);
-                    out.writeShort(cp.getFieldRef(
-                        prim.wrapperClassName, "TYPE", "Ljava/lang/Class;"));
-
-                } else {
-                    codeClassForName(parameterTypes[i], out);
-                }
-
-                out.writeByte(opc_aastore);
-            }
-
-            out.writeByte(opc_invokevirtual);
-            out.writeShort(cp.getMethodRef(
-                "java/lang/Class",
-                "getMethod",
-                "(Ljava/lang/String;[Ljava/lang/Class;)" +
-                "Ljava/lang/reflect/Method;"));
-
-            out.writeByte(opc_putstatic);
-            out.writeShort(cp.getFieldRef(
-                dotToSlash(className),
-                methodFieldName, "Ljava/lang/reflect/Method;"));
-        }
-    }
-
-    /**
-     * Generate the constructor method for the proxy class.
-     */
-    private MethodInfo generateConstructor() throws IOException {
-        MethodInfo minfo = new MethodInfo(
-            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V",
-            ACC_PUBLIC);
-
-        DataOutputStream out = new DataOutputStream(minfo.code);
-
-        code_aload(0, out);
-
-        code_aload(1, out);
-
-        out.writeByte(opc_invokespecial);
-        out.writeShort(cp.getMethodRef(
-            superclassName,
-            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V"));
-
-        out.writeByte(opc_return);
-
-        minfo.maxStack = 10;
-        minfo.maxLocals = 2;
-        minfo.declaredExceptions = new short[0];
-
-        return minfo;
-    }
-
-    /**
-     * Generate the static initializer method for the proxy class.
-     */
-    private MethodInfo generateStaticInitializer() throws IOException {
-        MethodInfo minfo = new MethodInfo(
-            "<clinit>", "()V", ACC_STATIC);
-
-        int localSlot0 = 1;
-        short pc, tryBegin = 0, tryEnd;
-
-        DataOutputStream out = new DataOutputStream(minfo.code);
-
-        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
-            for (ProxyMethod pm : sigmethods) {
-                pm.codeFieldInitialization(out);
-            }
-        }
-
-        out.writeByte(opc_return);
-
-        tryEnd = pc = (short) minfo.code.size();
-
-        minfo.exceptionTable.add(new ExceptionTableEntry(
-            tryBegin, tryEnd, pc,
-            cp.getClass("java/lang/NoSuchMethodException")));
-
-        code_astore(localSlot0, out);
-
-        out.writeByte(opc_new);
-        out.writeShort(cp.getClass("java/lang/NoSuchMethodError"));
-
-        out.writeByte(opc_dup);
-
-        code_aload(localSlot0, out);
-
-        out.writeByte(opc_invokevirtual);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
-
-        out.writeByte(opc_invokespecial);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/NoSuchMethodError", "<init>", "(Ljava/lang/String;)V"));
-
-        out.writeByte(opc_athrow);
-
-        pc = (short) minfo.code.size();
-
-        minfo.exceptionTable.add(new ExceptionTableEntry(
-            tryBegin, tryEnd, pc,
-            cp.getClass("java/lang/ClassNotFoundException")));
-
-        code_astore(localSlot0, out);
-
-        out.writeByte(opc_new);
-        out.writeShort(cp.getClass("java/lang/NoClassDefFoundError"));
-
-        out.writeByte(opc_dup);
-
-        code_aload(localSlot0, out);
-
-        out.writeByte(opc_invokevirtual);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
-
-        out.writeByte(opc_invokespecial);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/NoClassDefFoundError",
-            "<init>", "(Ljava/lang/String;)V"));
-
-        out.writeByte(opc_athrow);
-
-        if (minfo.code.size() > 65535) {
-            throw new IllegalArgumentException("code size limit exceeded");
-        }
-
-        minfo.maxStack = 10;
-        minfo.maxLocals = (short) (localSlot0 + 1);
-        minfo.declaredExceptions = new short[0];
-
-        return minfo;
-    }
-
-
-    /*
-     * =============== Code Generation Utility Methods ===============
-     */
-
-    /*
-     * The following methods generate code for the load or store operation
-     * indicated by their name for the given local variable.  The code is
-     * written to the supplied stream.
-     */
-
-    private void code_iload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_iload, opc_iload_0, out);
-    }
-
-    private void code_lload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_lload, opc_lload_0, out);
-    }
-
-    private void code_fload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_fload, opc_fload_0, out);
-    }
-
-    private void code_dload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_dload, opc_dload_0, out);
-    }
-
-    private void code_aload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_aload, opc_aload_0, out);
-    }
-
-//  private void code_istore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_istore, opc_istore_0, out);
-//  }
-
-//  private void code_lstore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_lstore, opc_lstore_0, out);
-//  }
-
-//  private void code_fstore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_fstore, opc_fstore_0, out);
-//  }
-
-//  private void code_dstore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_dstore, opc_dstore_0, out);
-//  }
-
-    private void code_astore(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_astore, opc_astore_0, out);
-    }
-
-    /**
-     * Generate code for a load or store instruction for the given local
-     * variable.  The code is written to the supplied stream.
-     *
-     * "opcode" indicates the opcode form of the desired load or store
-     * instruction that takes an explicit local variable index, and
-     * "opcode_0" indicates the corresponding form of the instruction
-     * with the implicit index 0.
-     */
-    private void codeLocalLoadStore(int lvar, int opcode, int opcode_0,
-                                    DataOutputStream out)
-        throws IOException
-    {
-        assert lvar >= 0 && lvar <= 0xFFFF;
-        if (lvar <= 3) {
-            out.writeByte(opcode_0 + lvar);
-        } else if (lvar <= 0xFF) {
-            out.writeByte(opcode);
-            out.writeByte(lvar & 0xFF);
-        } else {
-            /*
-             * Use the "wide" instruction modifier for local variable
-             * indexes that do not fit into an unsigned byte.
-             */
-            out.writeByte(opc_wide);
-            out.writeByte(opcode);
-            out.writeShort(lvar & 0xFFFF);
-        }
-    }
-
-    /**
-     * Generate code for an "ldc" instruction for the given constant pool
-     * index (the "ldc_w" instruction is used if the index does not fit
-     * into an unsigned byte).  The code is written to the supplied stream.
-     */
-    private void code_ldc(int index, DataOutputStream out)
-        throws IOException
-    {
-        assert index >= 0 && index <= 0xFFFF;
-        if (index <= 0xFF) {
-            out.writeByte(opc_ldc);
-            out.writeByte(index & 0xFF);
-        } else {
-            out.writeByte(opc_ldc_w);
-            out.writeShort(index & 0xFFFF);
-        }
-    }
-
-    /**
-     * Generate code to push a constant integer value on to the operand
-     * stack, using the "iconst_<i>", "bipush", or "sipush" instructions
-     * depending on the size of the value.  The code is written to the
-     * supplied stream.
-     */
-    private void code_ipush(int value, DataOutputStream out)
-        throws IOException
-    {
-        if (value >= -1 && value <= 5) {
-            out.writeByte(opc_iconst_0 + value);
-        } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
-            out.writeByte(opc_bipush);
-            out.writeByte(value & 0xFF);
-        } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
-            out.writeByte(opc_sipush);
-            out.writeShort(value & 0xFFFF);
-        } else {
-            throw new AssertionError();
-        }
-    }
-
-    /**
-     * Generate code to invoke the Class.forName with the name of the given
-     * class to get its Class object at runtime.  The code is written to
-     * the supplied stream.  Note that the code generated by this method
-     * may caused the checked ClassNotFoundException to be thrown.
-     */
-    private void codeClassForName(Class<?> cl, DataOutputStream out)
-        throws IOException
-    {
-        code_ldc(cp.getString(cl.getName()), out);
-
-        out.writeByte(opc_invokestatic);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/Class",
-            "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
-    }
-
-
-    /*
-     * ==================== General Utility Methods ====================
-     */
-
-    /**
-     * Convert a fully qualified class name that uses '.' as the package
-     * separator, the external representation used by the Java language
-     * and APIs, to a fully qualified class name that uses '/' as the
-     * package separator, the representation used in the class file
-     * format (see JVMS section 4.2).
-     */
-    private static String dotToSlash(String name) {
-        return name.replace('.', '/');
-    }
-
-    /**
-     * Return the "method descriptor" string for a method with the given
-     * parameter types and return type.  See JVMS section 4.3.3.
-     */
-    private static String getMethodDescriptor(Class<?>[] parameterTypes,
-                                              Class<?> returnType)
-    {
-        return getParameterDescriptors(parameterTypes) +
-            ((returnType == void.class) ? "V" : getFieldType(returnType));
-    }
-
-    /**
-     * Return the list of "parameter descriptor" strings enclosed in
-     * parentheses corresponding to the given parameter types (in other
-     * words, a method descriptor without a return descriptor).  This
-     * string is useful for constructing string keys for methods without
-     * regard to their return type.
-     */
-    private static String getParameterDescriptors(Class<?>[] parameterTypes) {
-        StringBuilder desc = new StringBuilder("(");
-        for (int i = 0; i < parameterTypes.length; i++) {
-            desc.append(getFieldType(parameterTypes[i]));
-        }
-        desc.append(')');
-        return desc.toString();
-    }
-
-    /**
-     * Return the "field type" string for the given type, appropriate for
-     * a field descriptor, a parameter descriptor, or a return descriptor
-     * other than "void".  See JVMS section 4.3.2.
-     */
-    private static String getFieldType(Class<?> type) {
-        if (type.isPrimitive()) {
-            return PrimitiveTypeInfo.get(type).baseTypeString;
-        } else if (type.isArray()) {
-            /*
-             * According to JLS 20.3.2, the getName() method on Class does
-             * return the VM type descriptor format for array classes (only);
-             * using that should be quicker than the otherwise obvious code:
-             *
-             *     return "[" + getTypeDescriptor(type.getComponentType());
-             */
-            return type.getName().replace('.', '/');
-        } else {
-            return "L" + dotToSlash(type.getName()) + ";";
-        }
-    }
-
-    /**
-     * Returns a human-readable string representing the signature of a
-     * method with the given name and parameter types.
-     */
-    private static String getFriendlyMethodSignature(String name,
-                                                     Class<?>[] parameterTypes)
-    {
-        StringBuilder sig = new StringBuilder(name);
-        sig.append('(');
-        for (int i = 0; i < parameterTypes.length; i++) {
-            if (i > 0) {
-                sig.append(',');
-            }
-            Class<?> parameterType = parameterTypes[i];
-            int dimensions = 0;
-            while (parameterType.isArray()) {
-                parameterType = parameterType.getComponentType();
-                dimensions++;
-            }
-            sig.append(parameterType.getName());
-            while (dimensions-- > 0) {
-                sig.append("[]");
-            }
-        }
-        sig.append(')');
-        return sig.toString();
-    }
-
-    /**
-     * Return the number of abstract "words", or consecutive local variable
-     * indexes, required to contain a value of the given type.  See JVMS
-     * section 3.6.1.
-     *
-     * Note that the original version of the JVMS contained a definition of
-     * this abstract notion of a "word" in section 3.4, but that definition
-     * was removed for the second edition.
-     */
-    private static int getWordsPerType(Class<?> type) {
-        if (type == long.class || type == double.class) {
-            return 2;
-        } else {
-            return 1;
-        }
-    }
-
-    /**
-     * Add to the given list all of the types in the "from" array that
-     * are not already contained in the list and are assignable to at
-     * least one of the types in the "with" array.
-     *
-     * This method is useful for computing the greatest common set of
-     * declared exceptions from duplicate methods inherited from
-     * different interfaces.
-     */
-    private static void collectCompatibleTypes(Class<?>[] from,
-                                               Class<?>[] with,
-                                               List<Class<?>> list)
-    {
-        for (Class<?> fc: from) {
-            if (!list.contains(fc)) {
-                for (Class<?> wc: with) {
-                    if (wc.isAssignableFrom(fc)) {
-                        list.add(fc);
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Given the exceptions declared in the throws clause of a proxy method,
-     * compute the exceptions that need to be caught from the invocation
-     * handler's invoke method and rethrown intact in the method's
-     * implementation before catching other Throwables and wrapping them
-     * in UndeclaredThrowableExceptions.
-     *
-     * The exceptions to be caught are returned in a List object.  Each
-     * exception in the returned list is guaranteed to not be a subclass of
-     * any of the other exceptions in the list, so the catch blocks for
-     * these exceptions may be generated in any order relative to each other.
-     *
-     * Error and RuntimeException are each always contained by the returned
-     * list (if none of their superclasses are contained), since those
-     * unchecked exceptions should always be rethrown intact, and thus their
-     * subclasses will never appear in the returned list.
-     *
-     * The returned List will be empty if java.lang.Throwable is in the
-     * given list of declared exceptions, indicating that no exceptions
-     * need to be caught.
-     */
-    private static List<Class<?>> computeUniqueCatchList(Class<?>[] exceptions) {
-        List<Class<?>> uniqueList = new ArrayList<>();
-                                                // unique exceptions to catch
-
-        uniqueList.add(Error.class);            // always catch/rethrow these
-        uniqueList.add(RuntimeException.class);
-
-    nextException:
-        for (Class<?> ex: exceptions) {
-            if (ex.isAssignableFrom(Throwable.class)) {
-                /*
-                 * If Throwable is declared to be thrown by the proxy method,
-                 * then no catch blocks are necessary, because the invoke
-                 * can, at most, throw Throwable anyway.
-                 */
-                uniqueList.clear();
-                break;
-            } else if (!Throwable.class.isAssignableFrom(ex)) {
-                /*
-                 * Ignore types that cannot be thrown by the invoke method.
-                 */
-                continue;
-            }
-            /*
-             * Compare this exception against the current list of
-             * exceptions that need to be caught:
-             */
-            for (int j = 0; j < uniqueList.size();) {
-                Class<?> ex2 = uniqueList.get(j);
-                if (ex2.isAssignableFrom(ex)) {
-                    /*
-                     * if a superclass of this exception is already on
-                     * the list to catch, then ignore this one and continue;
-                     */
-                    continue nextException;
-                } else if (ex.isAssignableFrom(ex2)) {
-                    /*
-                     * if a subclass of this exception is on the list
-                     * to catch, then remove it;
-                     */
-                    uniqueList.remove(j);
-                } else {
-                    j++;        // else continue comparing.
-                }
-            }
-            // This exception is unique (so far): add it to the list to catch.
-            uniqueList.add(ex);
-        }
-        return uniqueList;
-    }
-
-    /**
-     * A PrimitiveTypeInfo object contains assorted information about
-     * a primitive type in its public fields.  The struct for a particular
-     * primitive type can be obtained using the static "get" method.
-     */
-    private static class PrimitiveTypeInfo {
-
-        /** "base type" used in various descriptors (see JVMS section 4.3.2) */
-        public String baseTypeString;
-
-        /** name of corresponding wrapper class */
-        public String wrapperClassName;
-
-        /** method descriptor for wrapper class "valueOf" factory method */
-        public String wrapperValueOfDesc;
-
-        /** name of wrapper class method for retrieving primitive value */
-        public String unwrapMethodName;
-
-        /** descriptor of same method */
-        public String unwrapMethodDesc;
-
-        private static Map<Class<?>,PrimitiveTypeInfo> table = new HashMap<>();
-        static {
-            add(byte.class, Byte.class);
-            add(char.class, Character.class);
-            add(double.class, Double.class);
-            add(float.class, Float.class);
-            add(int.class, Integer.class);
-            add(long.class, Long.class);
-            add(short.class, Short.class);
-            add(boolean.class, Boolean.class);
-        }
-
-        private static void add(Class<?> primitiveClass, Class<?> wrapperClass) {
-            table.put(primitiveClass,
-                      new PrimitiveTypeInfo(primitiveClass, wrapperClass));
-        }
-
-        private PrimitiveTypeInfo(Class<?> primitiveClass, Class<?> wrapperClass) {
-            assert primitiveClass.isPrimitive();
-
-            baseTypeString =
-                Array.newInstance(primitiveClass, 0)
-                .getClass().getName().substring(1);
-            wrapperClassName = dotToSlash(wrapperClass.getName());
-            wrapperValueOfDesc =
-                "(" + baseTypeString + ")L" + wrapperClassName + ";";
-            unwrapMethodName = primitiveClass.getName() + "Value";
-            unwrapMethodDesc = "()" + baseTypeString;
-        }
-
-        public static PrimitiveTypeInfo get(Class<?> cl) {
-            return table.get(cl);
-        }
-    }
-
-
-    /**
-     * A ConstantPool object represents the constant pool of a class file
-     * being generated.  This representation of a constant pool is designed
-     * specifically for use by ProxyGenerator; in particular, it assumes
-     * that constant pool entries will not need to be resorted (for example,
-     * by their type, as the Java compiler does), so that the final index
-     * value can be assigned and used when an entry is first created.
-     *
-     * Note that new entries cannot be created after the constant pool has
-     * been written to a class file.  To prevent such logic errors, a
-     * ConstantPool instance can be marked "read only", so that further
-     * attempts to add new entries will fail with a runtime exception.
-     *
-     * See JVMS section 4.4 for more information about the constant pool
-     * of a class file.
-     */
-    private static class ConstantPool {
-
-        /**
-         * list of constant pool entries, in constant pool index order.
-         *
-         * This list is used when writing the constant pool to a stream
-         * and for assigning the next index value.  Note that element 0
-         * of this list corresponds to constant pool index 1.
-         */
-        private List<Entry> pool = new ArrayList<>(32);
-
-        /**
-         * maps constant pool data of all types to constant pool indexes.
-         *
-         * This map is used to look up the index of an existing entry for
-         * values of all types.
-         */
-        private Map<Object,Short> map = new HashMap<>(16);
-
-        /** true if no new constant pool entries may be added */
-        private boolean readOnly = false;
-
-        /**
-         * Get or assign the index for a CONSTANT_Utf8 entry.
-         */
-        public short getUtf8(String s) {
-            if (s == null) {
-                throw new NullPointerException();
-            }
-            return getValue(s);
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_Integer entry.
-         */
-        public short getInteger(int i) {
-            return getValue(i);
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_Float entry.
-         */
-        public short getFloat(float f) {
-            return getValue(new Float(f));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_Class entry.
-         */
-        public short getClass(String name) {
-            short utf8Index = getUtf8(name);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_CLASS, utf8Index));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_String entry.
-         */
-        public short getString(String s) {
-            short utf8Index = getUtf8(s);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_STRING, utf8Index));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_FieldRef entry.
-         */
-        public short getFieldRef(String className,
-                                 String name, String descriptor)
-        {
-            short classIndex = getClass(className);
-            short nameAndTypeIndex = getNameAndType(name, descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_FIELD, classIndex, nameAndTypeIndex));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_MethodRef entry.
-         */
-        public short getMethodRef(String className,
-                                  String name, String descriptor)
-        {
-            short classIndex = getClass(className);
-            short nameAndTypeIndex = getNameAndType(name, descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_METHOD, classIndex, nameAndTypeIndex));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_InterfaceMethodRef entry.
-         */
-        public short getInterfaceMethodRef(String className, String name,
-                                           String descriptor)
-        {
-            short classIndex = getClass(className);
-            short nameAndTypeIndex = getNameAndType(name, descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_INTERFACEMETHOD, classIndex, nameAndTypeIndex));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_NameAndType entry.
-         */
-        public short getNameAndType(String name, String descriptor) {
-            short nameIndex = getUtf8(name);
-            short descriptorIndex = getUtf8(descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_NAMEANDTYPE, nameIndex, descriptorIndex));
-        }
-
-        /**
-         * Set this ConstantPool instance to be "read only".
-         *
-         * After this method has been called, further requests to get
-         * an index for a non-existent entry will cause an InternalError
-         * to be thrown instead of creating of the entry.
-         */
-        public void setReadOnly() {
-            readOnly = true;
-        }
-
-        /**
-         * Write this constant pool to a stream as part of
-         * the class file format.
-         *
-         * This consists of writing the "constant_pool_count" and
-         * "constant_pool[]" items of the "ClassFile" structure, as
-         * described in JVMS section 4.1.
-         */
-        public void write(OutputStream out) throws IOException {
-            DataOutputStream dataOut = new DataOutputStream(out);
-
-            // constant_pool_count: number of entries plus one
-            dataOut.writeShort(pool.size() + 1);
-
-            for (Entry e : pool) {
-                e.write(dataOut);
-            }
-        }
-
-        /**
-         * Add a new constant pool entry and return its index.
-         */
-        private short addEntry(Entry entry) {
-            pool.add(entry);
-            /*
-             * Note that this way of determining the index of the
-             * added entry is wrong if this pool supports
-             * CONSTANT_Long or CONSTANT_Double entries.
-             */
-            if (pool.size() >= 65535) {
-                throw new IllegalArgumentException(
-                    "constant pool size limit exceeded");
-            }
-            return (short) pool.size();
-        }
-
-        /**
-         * Get or assign the index for an entry of a type that contains
-         * a direct value.  The type of the given object determines the
-         * type of the desired entry as follows:
-         *
-         *      java.lang.String        CONSTANT_Utf8
-         *      java.lang.Integer       CONSTANT_Integer
-         *      java.lang.Float         CONSTANT_Float
-         *      java.lang.Long          CONSTANT_Long
-         *      java.lang.Double        CONSTANT_DOUBLE
-         */
-        private short getValue(Object key) {
-            Short index = map.get(key);
-            if (index != null) {
-                return index.shortValue();
-            } else {
-                if (readOnly) {
-                    throw new InternalError(
-                        "late constant pool addition: " + key);
-                }
-                short i = addEntry(new ValueEntry(key));
-                map.put(key, i);
-                return i;
-            }
-        }
-
-        /**
-         * Get or assign the index for an entry of a type that contains
-         * references to other constant pool entries.
-         */
-        private short getIndirect(IndirectEntry e) {
-            Short index = map.get(e);
-            if (index != null) {
-                return index.shortValue();
-            } else {
-                if (readOnly) {
-                    throw new InternalError("late constant pool addition");
-                }
-                short i = addEntry(e);
-                map.put(e, i);
-                return i;
-            }
-        }
-
-        /**
-         * Entry is the abstact superclass of all constant pool entry types
-         * that can be stored in the "pool" list; its purpose is to define a
-         * common method for writing constant pool entries to a class file.
-         */
-        private abstract static class Entry {
-            public abstract void write(DataOutputStream out)
-                throws IOException;
-        }
-
-        /**
-         * ValueEntry represents a constant pool entry of a type that
-         * contains a direct value (see the comments for the "getValue"
-         * method for a list of such types).
-         *
-         * ValueEntry objects are not used as keys for their entries in the
-         * Map "map", so no useful hashCode or equals methods are defined.
-         */
-        private static class ValueEntry extends Entry {
-            private Object value;
-
-            public ValueEntry(Object value) {
-                this.value = value;
-            }
-
-            public void write(DataOutputStream out) throws IOException {
-                if (value instanceof String) {
-                    out.writeByte(CONSTANT_UTF8);
-                    out.writeUTF((String) value);
-                } else if (value instanceof Integer) {
-                    out.writeByte(CONSTANT_INTEGER);
-                    out.writeInt(((Integer) value).intValue());
-                } else if (value instanceof Float) {
-                    out.writeByte(CONSTANT_FLOAT);
-                    out.writeFloat(((Float) value).floatValue());
-                } else if (value instanceof Long) {
-                    out.writeByte(CONSTANT_LONG);
-                    out.writeLong(((Long) value).longValue());
-                } else if (value instanceof Double) {
-                    out.writeDouble(CONSTANT_DOUBLE);
-                    out.writeDouble(((Double) value).doubleValue());
-                } else {
-                    throw new InternalError("bogus value entry: " + value);
-                }
-            }
-        }
-
-        /**
-         * IndirectEntry represents a constant pool entry of a type that
-         * references other constant pool entries, i.e., the following types:
-         *
-         *      CONSTANT_Class, CONSTANT_String, CONSTANT_Fieldref,
-         *      CONSTANT_Methodref, CONSTANT_InterfaceMethodref, and
-         *      CONSTANT_NameAndType.
-         *
-         * Each of these entry types contains either one or two indexes of
-         * other constant pool entries.
-         *
-         * IndirectEntry objects are used as the keys for their entries in
-         * the Map "map", so the hashCode and equals methods are overridden
-         * to allow matching.
-         */
-        private static class IndirectEntry extends Entry {
-            private int tag;
-            private short index0;
-            private short index1;
-
-            /**
-             * Construct an IndirectEntry for a constant pool entry type
-             * that contains one index of another entry.
-             */
-            public IndirectEntry(int tag, short index) {
-                this.tag = tag;
-                this.index0 = index;
-                this.index1 = 0;
-            }
-
-            /**
-             * Construct an IndirectEntry for a constant pool entry type
-             * that contains two indexes for other entries.
-             */
-            public IndirectEntry(int tag, short index0, short index1) {
-                this.tag = tag;
-                this.index0 = index0;
-                this.index1 = index1;
-            }
-
-            public void write(DataOutputStream out) throws IOException {
-                out.writeByte(tag);
-                out.writeShort(index0);
-                /*
-                 * If this entry type contains two indexes, write
-                 * out the second, too.
-                 */
-                if (tag == CONSTANT_FIELD ||
-                    tag == CONSTANT_METHOD ||
-                    tag == CONSTANT_INTERFACEMETHOD ||
-                    tag == CONSTANT_NAMEANDTYPE)
-                {
-                    out.writeShort(index1);
-                }
-            }
-
-            public int hashCode() {
-                return tag + index0 + index1;
-            }
-
-            public boolean equals(Object obj) {
-                if (obj instanceof IndirectEntry) {
-                    IndirectEntry other = (IndirectEntry) obj;
-                    if (tag == other.tag &&
-                        index0 == other.index0 && index1 == other.index1)
-                    {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/Queue.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-/**
- * Queue: implements a simple queue mechanism.  Allows for enumeration of the
- * elements.
- *
- * @author Herb Jellinek
- */
-
-public class Queue<T> {
-
-    int length = 0;
-
-    QueueElement<T> head = null;
-    QueueElement<T> tail = null;
-
-    public Queue() {
-    }
-
-    /**
-     * Enqueue an object.
-     */
-    public synchronized void enqueue(T obj) {
-
-        QueueElement<T> newElt = new QueueElement<>(obj);
-
-        if (head == null) {
-            head = newElt;
-            tail = newElt;
-            length = 1;
-        } else {
-            newElt.next = head;
-            head.prev = newElt;
-            head = newElt;
-            length++;
-        }
-        notify();
-    }
-
-    /**
-     * Dequeue the oldest object on the queue.  Will wait indefinitely.
-     *
-     * @return    the oldest object on the queue.
-     * @exception java.lang.InterruptedException if any thread has
-     *              interrupted this thread.
-     */
-    public T dequeue() throws InterruptedException {
-        return dequeue(0L);
-    }
-
-    /**
-     * Dequeue the oldest object on the queue.
-     * @param timeOut the number of milliseconds to wait for something
-     * to arrive.
-     *
-     * @return    the oldest object on the queue.
-     * @exception java.lang.InterruptedException if any thread has
-     *              interrupted this thread.
-     */
-    public synchronized T dequeue(long timeOut)
-        throws InterruptedException {
-
-        while (tail == null) {
-            wait(timeOut);
-        }
-        QueueElement<T> elt = tail;
-        tail = elt.prev;
-        if (tail == null) {
-            head = null;
-        } else {
-            tail.next = null;
-        }
-        length--;
-        return elt.obj;
-    }
-
-    /**
-     * Is the queue empty?
-     * @return true if the queue is empty.
-     */
-    public synchronized boolean isEmpty() {
-        return (tail == null);
-    }
-
-    /**
-     * Returns an enumeration of the elements in Last-In, First-Out
-     * order. Use the Enumeration methods on the returned object to
-     * fetch the elements sequentially.
-     */
-    public final synchronized Enumeration<T> elements() {
-        return new LIFOQueueEnumerator<>(this);
-    }
-
-    /**
-     * Returns an enumeration of the elements in First-In, First-Out
-     * order. Use the Enumeration methods on the returned object to
-     * fetch the elements sequentially.
-     */
-    public final synchronized Enumeration<T> reverseElements() {
-        return new FIFOQueueEnumerator<>(this);
-    }
-
-    public synchronized void dump(String msg) {
-        System.err.println(">> "+msg);
-        System.err.println("["+length+" elt(s); head = "+
-                           (head == null ? "null" : (head.obj)+"")+
-                           " tail = "+(tail == null ? "null" : (tail.obj)+""));
-        QueueElement<T> cursor = head;
-        QueueElement<T> last = null;
-        while (cursor != null) {
-            System.err.println("  "+cursor);
-            last = cursor;
-            cursor = cursor.next;
-        }
-        if (last != tail) {
-            System.err.println("  tail != last: "+tail+", "+last);
-        }
-        System.err.println("]");
-    }
-}
-
-final class FIFOQueueEnumerator<T> implements Enumeration<T> {
-    Queue<T> queue;
-    QueueElement<T> cursor;
-
-    FIFOQueueEnumerator(Queue<T> q) {
-        queue = q;
-        cursor = q.tail;
-    }
-
-    public boolean hasMoreElements() {
-        return (cursor != null);
-    }
-
-    public T nextElement() {
-        synchronized (queue) {
-            if (cursor != null) {
-                QueueElement<T> result = cursor;
-                cursor = cursor.prev;
-                return result.obj;
-            }
-        }
-        throw new NoSuchElementException("FIFOQueueEnumerator");
-    }
-}
-
-final class LIFOQueueEnumerator<T> implements Enumeration<T> {
-    Queue<T> queue;
-    QueueElement<T> cursor;
-
-    LIFOQueueEnumerator(Queue<T> q) {
-        queue = q;
-        cursor = q.head;
-    }
-
-    public boolean hasMoreElements() {
-        return (cursor != null);
-    }
-
-    public T nextElement() {
-        synchronized (queue) {
-            if (cursor != null) {
-                QueueElement<T> result = cursor;
-                cursor = cursor.next;
-                return result.obj;
-            }
-        }
-        throw new NoSuchElementException("LIFOQueueEnumerator");
-    }
-}
-
-class QueueElement<T> {
-    QueueElement<T> next = null;
-    QueueElement<T> prev = null;
-
-    T obj = null;
-
-    QueueElement(T obj) {
-        this.obj = obj;
-    }
-
-    public String toString() {
-        return "QueueElement[obj="+obj+(prev == null ? " null" : " prev")+
-            (next == null ? " null" : " next")+"]";
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/Request.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/**
- * Requests are functor objects; that is, they provide part of the mechanism
- * for deferred function application.
- *
- * @author      Steven B. Byrne
- */
-
-public abstract class Request {
-    /**
-     * The main task of the Request object is to be exectuted from a request
-     * queue.
-     */
-    public abstract void execute();
-}
--- a/jdk/src/java.base/share/classes/sun/misc/RequestProcessor.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/**
- * The request processor allows functors (Request instances) to be created
- * in arbitrary threads, and to be posted for execution in a non-restricted
- * thread.
- *
- * @author      Steven B. Byrne
- */
-
-
-public class RequestProcessor implements Runnable {
-
-    private static Queue<Request> requestQueue;
-    private static Thread dispatcher;
-
-    /**
-     * Queues a Request instance for execution by the request procesor
-     * thread.
-     */
-    public static void postRequest(Request req) {
-        lazyInitialize();
-        requestQueue.enqueue(req);
-    }
-
-    /**
-     * Process requests as they are queued.
-     */
-    public void run() {
-        lazyInitialize();
-        while (true) {
-            try {
-                Request req = requestQueue.dequeue();
-                try {
-                    req.execute();
-                } catch (Throwable t) {
-                    // do nothing at the moment...maybe report an error
-                    // in the future
-                }
-            } catch (InterruptedException e) {
-                // do nothing at the present time.
-            }
-        }
-    }
-
-
-    /**
-     * This method initiates the request processor thread.  It is safe
-     * to call it after the thread has been started.  It provides a way for
-     * clients to deliberately control the context in which the request
-     * processor thread is created
-     */
-    public static synchronized void startProcessing() {
-        if (dispatcher == null) {
-            dispatcher = new ManagedLocalsThread(new RequestProcessor(), "Request Processor");
-            dispatcher.setPriority(Thread.NORM_PRIORITY + 2);
-            dispatcher.start();
-        }
-    }
-
-
-    /**
-     * This method performs lazy initialization.
-     */
-    private static synchronized void lazyInitialize() {
-        if (requestQueue == null) {
-            requestQueue = new Queue<Request>();
-        }
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/misc/Signal.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/Signal.java	Tue Dec 22 13:41:12 2015 -0800
@@ -213,7 +213,7 @@
             }
         };
         if (handler != null) {
-            new ManagedLocalsThread(runnable, sig + " handler").start();
+            new Thread(null, runnable, sig + " handler", 0, false).start();
         }
     }
 
--- a/jdk/src/java.base/share/classes/sun/misc/UCDecoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 1995, 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.PushbackInputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-
-/**
- * This class implements a robust character decoder. The decoder will
- * converted encoded text into binary data.
- *
- * The basic encoding unit is a 3 character atom. It encodes two bytes
- * of data. Bytes are encoded into a 64 character set, the characters
- * were chosen specifically because they appear in all codesets.
- * We don't care what their numerical equivalent is because
- * we use a character array to map them. This is like UUencoding
- * with the dependency on ASCII removed.
- *
- * The three chars that make up an atom are encoded as follows:
- * <pre>
- *      00xxxyyy 00axxxxx 00byyyyy
- *      00 = leading zeros, all values are 0 - 63
- *      xxxyyy - Top 3 bits of X, Top 3 bits of Y
- *      axxxxx - a = X parity bit, xxxxx lower 5 bits of X
- *      byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
- * </pre>
- *
- * The atoms are arranged into lines suitable for inclusion into an
- * email message or text file. The number of bytes that are encoded
- * per line is 48 which keeps the total line length  under 80 chars)
- *
- * Each line has the form(
- * <pre>
- *  *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
- *  Where each (xxx) represents a three character atom.
- *  (LLSS) - 8 bit length (high byte), and sequence number
- *           modulo 256;
- *  (DDDD) - Data byte atoms, if length is odd, last data
- *           atom has (DD00) (high byte data, low byte 0)
- *  (CRC)  - 16 bit CRC for the line, includes length,
- *           sequence, and all data bytes. If there is a
- *           zero pad byte (odd length) it is _NOT_
- *           included in the CRC.
- * </pre>
- *
- * If an error is encountered during decoding this class throws a
- * CEFormatException. The specific detail messages are:
- *
- * <pre>
- *    "UCDecoder: High byte parity error."
- *    "UCDecoder: Low byte parity error."
- *    "UCDecoder: Out of sequence line."
- *    "UCDecoder: CRC check failed."
- * </pre>
- *
- * @author      Chuck McManis
- * @see         CharacterEncoder
- * @see         UCEncoder
- */
-public class UCDecoder extends CharacterDecoder {
-
-    /** This class encodes two bytes per atom. */
-    protected int bytesPerAtom() {
-        return (2);
-    }
-
-    /** this class encodes 48 bytes per line */
-    protected int bytesPerLine() {
-        return (48);
-    }
-
-    /* this is the UCE mapping of 0-63 to characters .. */
-    private static final byte map_array[] = {
-        //     0         1         2         3         4         5         6         7
-        (byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7', // 0
-        (byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F', // 1
-        (byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N', // 2
-        (byte)'O',(byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V', // 3
-        (byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', // 4
-        (byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l', // 5
-        (byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s',(byte)'t', // 6
-        (byte)'u',(byte)'v',(byte)'w',(byte)'x',(byte)'y',(byte)'z',(byte)'(',(byte)')'  // 7
-    };
-
-    private int sequence;
-    private byte tmp[] = new byte[2];
-    private CRC16 crc = new CRC16();
-
-    /**
-     * Decode one atom - reads the characters from the input stream, decodes
-     * them, and checks for valid parity.
-     */
-    protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l) throws IOException {
-        int i, p1, p2, np1, np2;
-        byte a = -1, b = -1, c = -1;
-        byte high_byte, low_byte;
-        byte tmp[] = new byte[3];
-
-        i = inStream.read(tmp);
-        if (i != 3) {
-                throw new CEStreamExhausted();
-        }
-        for (i = 0; (i < 64) && ((a == -1) || (b == -1) || (c == -1)); i++) {
-            if (tmp[0] == map_array[i]) {
-                a = (byte) i;
-            }
-            if (tmp[1] == map_array[i]) {
-                b = (byte) i;
-            }
-            if (tmp[2] == map_array[i]) {
-                c = (byte) i;
-            }
-        }
-        high_byte = (byte) (((a & 0x38) << 2) + (b & 0x1f));
-        low_byte = (byte) (((a & 0x7) << 5) + (c & 0x1f));
-        p1 = 0;
-        p2 = 0;
-        for (i = 1; i < 256; i = i * 2) {
-            if ((high_byte & i) != 0)
-                p1++;
-            if ((low_byte & i) != 0)
-                p2++;
-        }
-        np1 = (b & 32) / 32;
-        np2 = (c & 32) / 32;
-        if ((p1 & 1) != np1) {
-            throw new CEFormatException("UCDecoder: High byte parity error.");
-        }
-        if ((p2 & 1) != np2) {
-            throw new CEFormatException("UCDecoder: Low byte parity error.");
-        }
-        outStream.write(high_byte);
-        crc.update(high_byte);
-        if (l == 2) {
-            outStream.write(low_byte);
-            crc.update(low_byte);
-        }
-    }
-
-    private ByteArrayOutputStream lineAndSeq = new ByteArrayOutputStream(2);
-
-    /**
-     * decodeBufferPrefix initializes the sequence number to zero.
-     */
-    protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) {
-        sequence = 0;
-    }
-
-    /**
-     * decodeLinePrefix reads the sequence number and the number of
-     * encoded bytes from the line. If the sequence number is not the
-     * previous sequence number + 1 then an exception is thrown.
-     * UCE lines are line terminator immune, they all start with *
-     * so the other thing this method does is scan for the next line
-     * by looking for the * character.
-     *
-     * @exception CEFormatException out of sequence lines detected.
-     */
-    protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream)  throws IOException {
-        int     i;
-        int     nLen, nSeq;
-        byte    xtmp[];
-        int     c;
-
-        crc.value = 0;
-        while (true) {
-            c = inStream.read(tmp, 0, 1);
-            if (c == -1) {
-                throw new CEStreamExhausted();
-            }
-            if (tmp[0] == '*') {
-                break;
-            }
-        }
-        lineAndSeq.reset();
-        decodeAtom(inStream, lineAndSeq, 2);
-        xtmp = lineAndSeq.toByteArray();
-        nLen = xtmp[0] & 0xff;
-        nSeq = xtmp[1] & 0xff;
-        if (nSeq != sequence) {
-            throw new CEFormatException("UCDecoder: Out of sequence line.");
-        }
-        sequence = (sequence + 1) & 0xff;
-        return (nLen);
-    }
-
-
-    /**
-     * this method reads the CRC that is at the end of every line and
-     * verifies that it matches the computed CRC.
-     *
-     * @exception CEFormatException if CRC check fails.
-     */
-    protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
-        int i;
-        int lineCRC = crc.value;
-        int readCRC;
-        byte tmp[];
-
-        lineAndSeq.reset();
-        decodeAtom(inStream, lineAndSeq, 2);
-        tmp = lineAndSeq.toByteArray();
-        readCRC = ((tmp[0] << 8) & 0xFF00) + (tmp[1] & 0xff);
-        if (readCRC != lineCRC) {
-            throw new CEFormatException("UCDecoder: CRC check failed.");
-        }
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/UCEncoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-
-/**
- * This class implements a robust character encoder. The encoder is designed
- * to convert binary data into printable characters. The characters are
- * assumed to exist but they are not assumed to be ASCII, the complete set
- * is 0-9, A-Z, a-z, "(", and ")".
- *
- * The basic encoding unit is a 3 character atom. It encodes two bytes
- * of data. Bytes are encoded into a 64 character set, the characters
- * were chosen specifically because they appear in all codesets.
- * We don't care what their numerical equivalent is because
- * we use a character array to map them. This is like UUencoding
- * with the dependency on ASCII removed.
- *
- * The three chars that make up an atom are encoded as follows:
- * <pre>
- *      00xxxyyy 00axxxxx 00byyyyy
- *      00 = leading zeros, all values are 0 - 63
- *      xxxyyy - Top 3 bits of X, Top 3 bits of Y
- *      axxxxx - a = X parity bit, xxxxx lower 5 bits of X
- *      byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
- * </pre>
- *
- * The atoms are arranged into lines suitable for inclusion into an
- * email message or text file. The number of bytes that are encoded
- * per line is 48 which keeps the total line length  under 80 chars)
- *
- * Each line has the form(
- * <pre>
- *  *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
- *  Where each (xxx) represents a three character atom.
- *  (LLSS) - 8 bit length (high byte), and sequence number
- *           modulo 256;
- *  (DDDD) - Data byte atoms, if length is odd, last data
- *           atom has (DD00) (high byte data, low byte 0)
- *  (CRC)  - 16 bit CRC for the line, includes length,
- *           sequence, and all data bytes. If there is a
- *           zero pad byte (odd length) it is _NOT_
- *           included in the CRC.
- * </pre>
- *
- * @author      Chuck McManis
- * @see         CharacterEncoder
- * @see         UCDecoder
- */
-public class UCEncoder extends CharacterEncoder {
-
-    /** this clase encodes two bytes per atom */
-    protected int bytesPerAtom() {
-        return (2);
-    }
-
-    /** this class encodes 48 bytes per line */
-    protected int bytesPerLine() {
-        return (48);
-    }
-
-    /* this is the UCE mapping of 0-63 to characters .. */
-    private static final byte map_array[] = {
-        //     0         1         2         3         4         5         6         7
-        (byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7', // 0
-        (byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F', // 1
-        (byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N', // 2
-        (byte)'O',(byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V', // 3
-        (byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', // 4
-        (byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l', // 5
-        (byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s',(byte)'t', // 6
-        (byte)'u',(byte)'v',(byte)'w',(byte)'x',(byte)'y',(byte)'z',(byte)'(',(byte)')'  // 7
-    };
-
-    private int sequence;
-    private byte tmp[] = new byte[2];
-    private CRC16 crc = new CRC16();
-
-    /**
-     * encodeAtom - take two bytes and encode them into the correct
-     * three characters. If only one byte is to be encoded, the other
-     * must be zero. The padding byte is not included in the CRC computation.
-     */
-    protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len) throws IOException
-    {
-        int     i;
-        int     p1, p2; // parity bits
-        byte    a, b;
-
-        a = data[offset];
-        if (len == 2) {
-            b = data[offset+1];
-        } else {
-            b = 0;
-        }
-        crc.update(a);
-        if (len == 2) {
-            crc.update(b);
-        }
-        outStream.write(map_array[((a >>> 2) & 0x38) + ((b >>> 5) & 0x7)]);
-        p1 = 0; p2 = 0;
-        for (i = 1; i < 256; i = i * 2) {
-            if ((a & i) != 0) {
-                p1++;
-            }
-            if ((b & i) != 0) {
-                p2++;
-            }
-        }
-        p1 = (p1 & 1) * 32;
-        p2 = (p2 & 1) * 32;
-        outStream.write(map_array[(a & 31) + p1]);
-        outStream.write(map_array[(b & 31) + p2]);
-        return;
-    }
-
-    /**
-     * Each UCE encoded line starts with a prefix of '*[XXX]', where
-     * the sequence number and the length are encoded in the first
-     * atom.
-     */
-    protected void encodeLinePrefix(OutputStream outStream, int length) throws IOException {
-        outStream.write('*');
-        crc.value = 0;
-        tmp[0] = (byte) length;
-        tmp[1] = (byte) sequence;
-        sequence = (sequence + 1) & 0xff;
-        encodeAtom(outStream, tmp, 0, 2);
-    }
-
-
-    /**
-     * each UCE encoded line ends with YYY and encoded version of the
-     * 16 bit checksum. The most significant byte of the check sum
-     * is always encoded FIRST.
-     */
-    protected void encodeLineSuffix(OutputStream outStream) throws IOException {
-        tmp[0] = (byte) ((crc.value >>> 8) & 0xff);
-        tmp[1] = (byte) (crc.value & 0xff);
-        encodeAtom(outStream, tmp, 0, 2);
-        super.pStream.println();
-    }
-
-    /**
-     * The buffer prefix code is used to initialize the sequence number
-     * to zero.
-     */
-    protected void encodeBufferPrefix(OutputStream a) throws IOException {
-        sequence = 0;
-        super.encodeBufferPrefix(a);
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/UUDecoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 1995, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.PushbackInputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-
-/**
- * This class implements a Berkeley uu character decoder. This decoder
- * was made famous by the uudecode program.
- *
- * The basic character coding is algorithmic, taking 6 bits of binary
- * data and adding it to an ASCII ' ' (space) character. This converts
- * these six bits into a printable representation. Note that it depends
- * on the ASCII character encoding standard for english. Groups of three
- * bytes are converted into 4 characters by treating the three bytes
- * a four 6 bit groups, group 1 is byte 1's most significant six bits,
- * group 2 is byte 1's least significant two bits plus byte 2's four
- * most significant bits. etc.
- *
- * In this encoding, the buffer prefix is:
- * <pre>
- *     begin [mode] [filename]
- * </pre>
- *
- * This is followed by one or more lines of the form:
- * <pre>
- *      (len)(data)(data)(data) ...
- * </pre>
- * where (len) is the number of bytes on this line. Note that groupings
- * are always four characters, even if length is not a multiple of three
- * bytes. When less than three characters are encoded, the values of the
- * last remaining bytes is undefined and should be ignored.
- *
- * The last line of data in a uuencoded buffer is represented by a single
- * space character. This is translated by the decoding engine to a line
- * length of zero. This is immediately followed by a line which contains
- * the word 'end[newline]'
- *
- * If an error is encountered during decoding this class throws a
- * CEFormatException. The specific detail messages are:
- *
- * <pre>
- *      "UUDecoder: No begin line."
- *      "UUDecoder: Malformed begin line."
- *      "UUDecoder: Short Buffer."
- *      "UUDecoder: Bad Line Length."
- *      "UUDecoder: Missing 'end' line."
- * </pre>
- *
- * @author      Chuck McManis
- * @see         CharacterDecoder
- * @see         UUEncoder
- */
-public class UUDecoder extends CharacterDecoder {
-
-    /**
-     * This string contains the name that was in the buffer being decoded.
-     */
-    public String bufferName;
-
-    /**
-     * Represents UNIX(tm) mode bits. Generally three octal digits
-     * representing read, write, and execute permission of the owner,
-     * group owner, and  others. They should be interpreted as the bit groups:
-     * <pre>
-     * (owner) (group) (others)
-     *  rwx      rwx     rwx    (r = read, w = write, x = execute)
-     *</pre>
-     *
-     */
-    public int mode;
-
-
-    /**
-     * UU encoding specifies 3 bytes per atom.
-     */
-    protected int bytesPerAtom() {
-        return (3);
-    }
-
-    /**
-     * All UU lines have 45 bytes on them, for line length of 15*4+1 or 61
-     * characters per line.
-     */
-    protected int bytesPerLine() {
-        return (45);
-    }
-
-    /** This is used to decode the atoms */
-    private byte decoderBuffer[] = new byte[4];
-
-    /**
-     * Decode a UU atom. Note that if l is less than 3 we don't write
-     * the extra bits, however the encoder always encodes 4 character
-     * groups even when they are not needed.
-     */
-    protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l)
-        throws IOException {
-        int i, c1, c2, c3, c4;
-        int a, b, c;
-        StringBuilder x = new StringBuilder();
-
-        for (i = 0; i < 4; i++) {
-            c1 = inStream.read();
-            if (c1 == -1) {
-                throw new CEStreamExhausted();
-            }
-            x.append((char)c1);
-            decoderBuffer[i] = (byte) ((c1 - ' ') & 0x3f);
-        }
-        a = ((decoderBuffer[0] << 2) & 0xfc) | ((decoderBuffer[1] >>> 4) & 3);
-        b = ((decoderBuffer[1] << 4) & 0xf0) | ((decoderBuffer[2] >>> 2) & 0xf);
-        c = ((decoderBuffer[2] << 6) & 0xc0) | (decoderBuffer[3] & 0x3f);
-        outStream.write((byte)(a & 0xff));
-        if (l > 1) {
-            outStream.write((byte)( b & 0xff));
-        }
-        if (l > 2) {
-            outStream.write((byte)(c&0xff));
-        }
-    }
-
-    /**
-     * For uuencoded buffers, the data begins with a line of the form:
-     *          begin MODE FILENAME
-     * This line always starts in column 1.
-     */
-    protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
-        int     c;
-        StringBuilder q = new StringBuilder(32);
-        String r;
-        boolean sawNewLine;
-
-        /*
-         * This works by ripping through the buffer until it finds a 'begin'
-         * line or the end of the buffer.
-         */
-        sawNewLine = true;
-        while (true) {
-            c = inStream.read();
-            if (c == -1) {
-                throw new CEFormatException("UUDecoder: No begin line.");
-            }
-            if ((c == 'b')  && sawNewLine){
-                c = inStream.read();
-                if (c == 'e') {
-                    break;
-                }
-            }
-            sawNewLine = (c == '\n') || (c == '\r');
-        }
-
-        /*
-         * Now we think its begin, (we've seen ^be) so verify it here.
-         */
-        while ((c != '\n') && (c != '\r')) {
-            c = inStream.read();
-            if (c == -1) {
-                throw new CEFormatException("UUDecoder: No begin line.");
-            }
-            if ((c != '\n') && (c != '\r')) {
-                q.append((char)c);
-            }
-        }
-        r = q.toString();
-        if (r.indexOf(' ') != 3) {
-                throw new CEFormatException("UUDecoder: Malformed begin line.");
-        }
-        mode = Integer.parseInt(r.substring(4,7));
-        bufferName = r.substring(r.indexOf(' ',6)+1);
-        /*
-         * Check for \n after \r
-         */
-        if (c == '\r') {
-            c = inStream.read ();
-            if ((c != '\n') && (c != -1))
-                inStream.unread (c);
-        }
-    }
-
-    /**
-     * In uuencoded buffers, encoded lines start with a character that
-     * represents the number of bytes encoded in this line. The last
-     * line of input is always a line that starts with a single space
-     * character, which would be a zero length line.
-     */
-    protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
-        int     c;
-
-        c = inStream.read();
-        if (c == ' ') {
-            c = inStream.read(); /* discard the (first)trailing CR or LF  */
-            c = inStream.read(); /* check for a second one  */
-            if ((c != '\n') && (c != -1))
-                inStream.unread (c);
-            throw new CEStreamExhausted();
-        } else if (c == -1) {
-            throw new CEFormatException("UUDecoder: Short Buffer.");
-        }
-
-        c = (c - ' ') & 0x3f;
-        if (c > bytesPerLine()) {
-            throw new CEFormatException("UUDecoder: Bad Line Length.");
-        }
-        return (c);
-    }
-
-
-    /**
-     * Find the end of the line for the next operation.
-     * The following sequences are recognized as end-of-line
-     * CR, CR LF, or LF
-     */
-    protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException {
-        int c;
-        while (true) {
-            c = inStream.read();
-            if (c == -1) {
-                throw new CEStreamExhausted();
-            }
-            if (c == '\n') {
-                break;
-            }
-            if (c == '\r') {
-                c = inStream.read();
-                if ((c != '\n') && (c != -1)) {
-                    inStream.unread (c);
-                }
-                break;
-            }
-        }
-    }
-
-    /**
-     * UUencoded files have a buffer suffix which consists of the word
-     * end. This line should immediately follow the line with a single
-     * space in it.
-     */
-    protected void decodeBufferSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException  {
-        int     c;
-
-        c = inStream.read(decoderBuffer);
-        if ((decoderBuffer[0] != 'e') || (decoderBuffer[1] != 'n') ||
-            (decoderBuffer[2] != 'd')) {
-            throw new CEFormatException("UUDecoder: Missing 'end' line.");
-        }
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/misc/UUEncoder.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.IOException;
-
-/**
- * This class implements a Berkeley uu character encoder. This encoder
- * was made famous by uuencode program.
- *
- * The basic character coding is algorithmic, taking 6 bits of binary
- * data and adding it to an ASCII ' ' (space) character. This converts
- * these six bits into a printable representation. Note that it depends
- * on the ASCII character encoding standard for english. Groups of three
- * bytes are converted into 4 characters by treating the three bytes
- * a four 6 bit groups, group 1 is byte 1's most significant six bits,
- * group 2 is byte 1's least significant two bits plus byte 2's four
- * most significant bits. etc.
- *
- * In this encoding, the buffer prefix is:
- * <pre>
- *     begin [mode] [filename]
- * </pre>
- *
- * This is followed by one or more lines of the form:
- * <pre>
- *      (len)(data)(data)(data) ...
- * </pre>
- * where (len) is the number of bytes on this line. Note that groupings
- * are always four characters, even if length is not a multiple of three
- * bytes. When less than three characters are encoded, the values of the
- * last remaining bytes is undefined and should be ignored.
- *
- * The last line of data in a uuencoded file is represented by a single
- * space character. This is translated by the decoding engine to a line
- * length of zero. This is immediately followed by a line which contains
- * the word 'end[newline]'
- *
- * @author      Chuck McManis
- * @see         CharacterEncoder
- * @see         UUDecoder
- */
-public class UUEncoder extends CharacterEncoder {
-
-    /**
-     * This name is stored in the begin line.
-     */
-    private String bufferName;
-
-    /**
-     * Represents UNIX(tm) mode bits. Generally three octal digits representing
-     * read, write, and execute permission of the owner, group owner, and
-     * others. They should be interpreted as the bit groups:
-     * (owner) (group) (others)
-     *  rwx      rwx     rwx    (r = read, w = write, x = execute)
-     *
-     * By default these are set to 644 (UNIX rw-r--r-- permissions).
-     */
-    private int mode;
-
-
-    /**
-     * Default - buffer begin line will be:
-     * <pre>
-     *  begin 644 encoder.buf
-     * </pre>
-     */
-    public UUEncoder() {
-        bufferName = "encoder.buf";
-        mode = 644;
-    }
-
-    /**
-     * Specifies a name for the encoded buffer, begin line will be:
-     * <pre>
-     *  begin 644 [FNAME]
-     * </pre>
-     */
-    public UUEncoder(String fname) {
-        bufferName = fname;
-        mode = 644;
-    }
-
-    /**
-     * Specifies a name and mode for the encoded buffer, begin line will be:
-     * <pre>
-     *  begin [MODE] [FNAME]
-     * </pre>
-     */
-    public UUEncoder(String fname, int newMode) {
-        bufferName = fname;
-        mode = newMode;
-    }
-
-    /** number of bytes per atom in uuencoding is 3 */
-    protected int bytesPerAtom() {
-        return (3);
-    }
-
-    /** number of bytes per line in uuencoding is 45 */
-    protected int bytesPerLine() {
-        return (45);
-    }
-
-    /**
-     * encodeAtom - take three bytes and encodes them into 4 characters
-     * If len is less than 3 then remaining bytes are filled with '1'.
-     * This insures that the last line won't end in spaces and potentiallly
-     * be truncated.
-     */
-    protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len)
-        throws IOException {
-        byte    a, b = 1, c = 1;
-        int     c1, c2, c3, c4;
-
-        a = data[offset];
-        if (len > 1) {
-            b = data[offset+1];
-        }
-        if (len > 2) {
-            c = data[offset+2];
-        }
-
-        c1 = (a >>> 2) & 0x3f;
-        c2 = ((a << 4) & 0x30) | ((b >>> 4) & 0xf);
-        c3 = ((b << 2) & 0x3c) | ((c >>> 6) & 0x3);
-        c4 = c & 0x3f;
-        outStream.write(c1 + ' ');
-        outStream.write(c2 + ' ');
-        outStream.write(c3 + ' ');
-        outStream.write(c4 + ' ');
-        return;
-    }
-
-    /**
-     * Encode the line prefix which consists of the single character. The
-     * lenght is added to the value of ' ' (32 decimal) and printed.
-     */
-    protected void encodeLinePrefix(OutputStream outStream, int length)
-        throws IOException {
-        outStream.write((length & 0x3f) + ' ');
-    }
-
-
-    /**
-     * The line suffix for uuencoded files is simply a new line.
-     */
-    protected void encodeLineSuffix(OutputStream outStream) throws IOException {
-        pStream.println();
-    }
-
-    /**
-     * encodeBufferPrefix writes the begin line to the output stream.
-     */
-    protected void encodeBufferPrefix(OutputStream a) throws IOException {
-        super.pStream = new PrintStream(a);
-        super.pStream.print("begin "+mode+" ");
-        if (bufferName != null) {
-            super.pStream.println(bufferName);
-        } else {
-            super.pStream.println("encoder.bin");
-        }
-        super.pStream.flush();
-    }
-
-    /**
-     * encodeBufferSuffix writes the single line containing space (' ') and
-     * the line containing the word 'end' to the output stream.
-     */
-    protected void encodeBufferSuffix(OutputStream a) throws IOException {
-        super.pStream.println(" \nend");
-        super.pStream.flush();
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/misc/VM.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/VM.java	Tue Dec 22 13:41:12 2015 -0800
@@ -274,9 +274,6 @@
         // used by java.lang.Integer.IntegerCache
         props.remove("java.lang.Integer.IntegerCache.high");
 
-        // used by java.util.zip.ZipFile
-        props.remove("sun.zip.disableMemoryMapping");
-
         // used by sun.launcher.LauncherHelper
         props.remove("sun.java.launcher.diag");
     }
--- a/jdk/src/java.base/share/classes/sun/net/NetworkServer.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/net/NetworkServer.java	Tue Dec 22 13:41:12 2015 -0800
@@ -27,7 +27,6 @@
 import java.io.*;
 import java.net.Socket;
 import java.net.ServerSocket;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * This is the base class for network servers.  To define a new type
@@ -73,7 +72,7 @@
                     NetworkServer n = (NetworkServer)clone();
                     n.serverSocket = null;
                     n.clientSocket = ns;
-                    new ManagedLocalsThread(n).start();
+                    new Thread(null, n, "NetworkServer", 0, false).start();
                 } catch(Exception e) {
                     System.out.print("Server failure\n");
                     e.printStackTrace();
@@ -108,7 +107,7 @@
         for each new connection. */
     public final void startServer(int port) throws IOException {
         serverSocket = new ServerSocket(port, 50);
-        serverInstance = new ManagedLocalsThread(this);
+        serverInstance = new Thread(null, this, "NetworkServer", 0, false);
         serverInstance.start();
     }
 
--- a/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Tue Dec 22 13:41:12 2015 -0800
@@ -27,9 +27,8 @@
 import java.net.URL;
 import java.io.*;
 import java.util.StringTokenizer;
-import sun.misc.ManagedLocalsThread;
 
-class MimeLauncher extends ManagedLocalsThread {
+class MimeLauncher extends Thread {
     java.net.URLConnection uc;
     MimeEntry m;
     String genericTempFileTemplate;
@@ -38,7 +37,7 @@
 
     MimeLauncher (MimeEntry M, java.net.URLConnection uc,
                   InputStream is, String tempFileTemplate, String threadName) throws ApplicationLaunchException {
-        super(threadName);
+        super(null, null, threadName, 0, false);
         m = M;
         this.uc = uc;
         this.is = is;
--- a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,6 @@
 import java.security.PrivilegedAction;
 import java.io.IOException;
 import java.util.*;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Base implementation of background poller thread used in watch service
@@ -60,7 +59,7 @@
         AccessController.doPrivileged(new PrivilegedAction<>() {
             @Override
             public Object run() {
-                Thread thr = new ManagedLocalsThread(thisRunnable);
+                Thread thr = new Thread(null, thisRunnable, "FileSystemWatchService", 0, false);
                 thr.setDaemon(true);
                 thr.start();
                 return null;
--- a/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java	Tue Dec 22 13:41:12 2015 -0800
@@ -25,7 +25,6 @@
 
 package sun.nio.fs;
 
-import sun.misc.ManagedLocalsThread;
 import jdk.internal.misc.Unsafe;
 import java.util.concurrent.ExecutionException;
 
@@ -118,7 +117,7 @@
      * thread by writing into the memory location that it polls cooperatively.
      */
     static void runInterruptibly(Cancellable task) throws ExecutionException {
-        Thread t = new ManagedLocalsThread(task);
+        Thread t = new Thread(null, task, "NIO-Task", 0, false);
         t.start();
         boolean cancelledByInterrupt = false;
         while (t.isAlive()) {
--- a/jdk/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java	Tue Dec 22 13:41:12 2015 -0800
@@ -35,7 +35,6 @@
 import java.util.*;
 import java.util.concurrent.*;
 import com.sun.nio.file.SensitivityWatchEventModifier;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Simple WatchService implementation that uses periodic tasks to poll
@@ -59,7 +58,7 @@
             .newSingleThreadScheduledExecutor(new ThreadFactory() {
                  @Override
                  public Thread newThread(Runnable r) {
-                     Thread t = new ManagedLocalsThread(r);
+                     Thread t = new Thread(null, r, "FileSystemWatchService", 0, false);
                      t.setDaemon(true);
                      return t;
                  }});
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Tue Dec 22 13:41:12 2015 -0800
@@ -62,7 +62,7 @@
                     decl);
         if (type instanceof Class) {
             return new AnnotatedTypeBaseImpl(type,
-                    addNesting(type, currentLoc),
+                    currentLoc,
                     actualTypeAnnos,
                     allOnSameTarget,
                     decl);
@@ -74,7 +74,7 @@
                     decl);
         } else if (type instanceof ParameterizedType) {
             return new AnnotatedParameterizedTypeImpl((ParameterizedType)type,
-                    addNesting(type, currentLoc),
+                    currentLoc,
                     actualTypeAnnos,
                     allOnSameTarget,
                     decl);
@@ -88,7 +88,7 @@
         throw new AssertionError("Unknown instance of Type: " + type + "\nThis should not happen.");
     }
 
-    private static LocationInfo addNesting(Type type, LocationInfo addTo) {
+    public static LocationInfo nestingForType(Type type, LocationInfo addTo) {
         if (isArray(type))
             return addTo;
         if (type instanceof Class) {
@@ -96,13 +96,13 @@
             if (clz.getEnclosingClass() == null)
                 return addTo;
             if (Modifier.isStatic(clz.getModifiers()))
-                return addNesting(clz.getEnclosingClass(), addTo);
-            return addNesting(clz.getEnclosingClass(), addTo.pushInner());
+                return nestingForType(clz.getEnclosingClass(), addTo);
+            return nestingForType(clz.getEnclosingClass(), addTo.pushInner());
         } else if (type instanceof ParameterizedType) {
             ParameterizedType t = (ParameterizedType)type;
             if (t.getOwnerType() == null)
                 return addTo;
-            return addNesting(t.getOwnerType(), addTo.pushInner());
+            return nestingForType(t.getOwnerType(), addTo.pushInner());
         }
         return addTo;
     }
@@ -118,8 +118,9 @@
         return false;
     }
 
+    static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0];
     static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION,
-                                                            new TypeAnnotation[0], new TypeAnnotation[0], null);
+            EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY, null);
     static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0];
 
     private static class AnnotatedTypeBaseImpl implements AnnotatedType {
@@ -177,6 +178,30 @@
             return type;
         }
 
+        @Override
+        public AnnotatedType getAnnotatedOwnerType() {
+            if (!(type instanceof Class<?>))
+                throw new IllegalStateException("Can't compute owner");
+
+            Class<?> inner = (Class<?>)type;
+            Class<?> owner = inner.getDeclaringClass();
+            if (owner == null) // top-level, local or anonymous
+                return null;
+            if (inner.isPrimitive() || inner == Void.TYPE)
+                return null;
+
+            LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
+            TypeAnnotation[]all = getTypeAnnotations();
+            List<TypeAnnotation> l = new ArrayList<>(all.length);
+
+            for (TypeAnnotation t : all)
+                if (t.getLocationInfo().isSameLocationInfo(outerLoc))
+                    l.add(t);
+
+            return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
+
+        }
+
         // Implementation details
         final LocationInfo getLocation() {
             return location;
@@ -198,11 +223,17 @@
 
         @Override
         public AnnotatedType getAnnotatedGenericComponentType() {
-            return AnnotatedTypeFactory.buildAnnotatedType(getComponentType(),
-                                                           getLocation().pushArray(),
-                                                           getTypeAnnotations(),
-                                                           getTypeAnnotations(),
-                                                           getDecl());
+            Type t = getComponentType();
+            return AnnotatedTypeFactory.buildAnnotatedType(t,
+                    nestingForType(t, getLocation().pushArray()),
+                    getTypeAnnotations(),
+                    getTypeAnnotations(),
+                    getDecl());
+        }
+
+        @Override
+        public AnnotatedType getAnnotatedOwnerType() {
+            return null;
         }
 
         private Type getComponentType() {
@@ -227,6 +258,11 @@
             return getTypeVariable().getAnnotatedBounds();
         }
 
+        @Override
+        public AnnotatedType getAnnotatedOwnerType() {
+            return null;
+        }
+
         private TypeVariable<?> getTypeVariable() {
             return (TypeVariable)getType();
         }
@@ -248,19 +284,35 @@
             int initialCapacity = getTypeAnnotations().length;
             for (int i = 0; i < res.length; i++) {
                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
-                LocationInfo newLoc = getLocation().pushTypeArg((byte)i);
+                LocationInfo newLoc = nestingForType(arguments[i], getLocation().pushTypeArg((byte)i));
                 for (TypeAnnotation t : getTypeAnnotations())
                     if (t.getLocationInfo().isSameLocationInfo(newLoc))
                         l.add(t);
                 res[i] = buildAnnotatedType(arguments[i],
-                                            newLoc,
-                                            l.toArray(new TypeAnnotation[0]),
-                                            getTypeAnnotations(),
-                                            getDecl());
+                        newLoc,
+                        l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
+                        getTypeAnnotations(),
+                        getDecl());
             }
             return res;
         }
 
+        @Override
+        public AnnotatedType getAnnotatedOwnerType() {
+            Type owner = getParameterizedType().getOwnerType();
+            if (owner == null)
+                return null;
+            LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
+            TypeAnnotation[]all = getTypeAnnotations();
+            List<TypeAnnotation> l = new ArrayList<>(all.length);
+
+            for (TypeAnnotation t : all)
+                if (t.getLocationInfo().isSameLocationInfo(outerLoc))
+                    l.add(t);
+
+            return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
+        }
+
         private ParameterizedType getParameterizedType() {
             return (ParameterizedType)getType();
         }
@@ -279,11 +331,11 @@
         public AnnotatedType[] getAnnotatedUpperBounds() {
             if (!hasUpperBounds()) {
                 return new AnnotatedType[] { buildAnnotatedType(Object.class,
-                                                                LocationInfo.BASE_LOCATION,
-                                                                new TypeAnnotation[0],
-                                                                new TypeAnnotation[0],
-                                                                null)
-                                           };
+                        LocationInfo.BASE_LOCATION,
+                        EMPTY_TYPE_ANNOTATION_ARRAY,
+                        EMPTY_TYPE_ANNOTATION_ARRAY,
+                        null)
+                };
             }
             return getAnnotatedBounds(getWildcardType().getUpperBounds());
         }
@@ -295,21 +347,26 @@
             return getAnnotatedBounds(getWildcardType().getLowerBounds());
         }
 
+        @Override
+        public AnnotatedType getAnnotatedOwnerType() {
+            return null;
+        }
+
         private AnnotatedType[] getAnnotatedBounds(Type[] bounds) {
             AnnotatedType[] res = new AnnotatedType[bounds.length];
             Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
-            LocationInfo newLoc = getLocation().pushWildcard();
             int initialCapacity = getTypeAnnotations().length;
             for (int i = 0; i < res.length; i++) {
+                LocationInfo newLoc = nestingForType(bounds[i], getLocation().pushWildcard());
                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
                 for (TypeAnnotation t : getTypeAnnotations())
                     if (t.getLocationInfo().isSameLocationInfo(newLoc))
                         l.add(t);
                 res[i] = buildAnnotatedType(bounds[i],
-                                            newLoc,
-                                            l.toArray(new TypeAnnotation[0]),
-                                            getTypeAnnotations(),
-                                            getDecl());
+                        newLoc,
+                        l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
+                        getTypeAnnotations(),
+                        getDecl());
             }
             return res;
         }
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotation.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotation.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -187,13 +187,28 @@
             return new LocationInfo(newDepth, res);
         }
 
+        /** Pop a series of locations matching {@code tag}. Stop poping as soon as a non-matching tag is found. */
+        public LocationInfo popAllLocations(byte tag) {
+            LocationInfo l = this;
+            int newDepth = l.depth;
+            while(newDepth > 0 && l.locations[newDepth - 1].tag == tag) {
+                newDepth--;
+            }
+            if (newDepth != l.depth) {
+                Location[] res = new Location[newDepth];
+                System.arraycopy(this.locations, 0, res, 0, newDepth);
+                return new LocationInfo(newDepth, res);
+            } else
+                return l;
+        }
+
         public TypeAnnotation[] filter(TypeAnnotation[] ta) {
             ArrayList<TypeAnnotation> l = new ArrayList<>(ta.length);
             for (TypeAnnotation t : ta) {
                 if (isSameLocationInfo(t.getLocationInfo()))
                     l.add(t);
             }
-            return l.toArray(new TypeAnnotation[0]);
+            return l.toArray(AnnotatedTypeFactory.EMPTY_TYPE_ANNOTATION_ARRAY);
         }
 
         boolean isSameLocationInfo(LocationInfo other) {
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import jdk.internal.misc.SharedSecrets;
@@ -67,9 +66,8 @@
             Type type,
             TypeAnnotationTarget filter) {
         TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
-                                                    cp,
-                                                    decl,
-                                                    container);
+                cp, decl, container);
+
         List<TypeAnnotation> l = new ArrayList<>(tas.length);
         for (TypeAnnotation t : tas) {
             TypeAnnotationTargetInfo ti = t.getTargetInfo();
@@ -78,10 +76,10 @@
         }
         TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
         return AnnotatedTypeFactory.buildAnnotatedType(type,
-                                                       LocationInfo.BASE_LOCATION,
-                                                       typeAnnotations,
-                                                       typeAnnotations,
-                                                       decl);
+                AnnotatedTypeFactory.nestingForType(type, LocationInfo.BASE_LOCATION),
+                typeAnnotations,
+                typeAnnotations,
+                decl);
     }
 
     /**
@@ -110,9 +108,8 @@
         ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation>
 
         TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
-                                                    cp,
-                                                    decl,
-                                                    container);
+                cp, decl, container);
+
         for (TypeAnnotation t : tas) {
             TypeAnnotationTargetInfo ti = t.getTargetInfo();
             if (ti.getTarget() == filter) {
@@ -136,10 +133,10 @@
                 typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY;
             }
             result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
-                                                                LocationInfo.BASE_LOCATION,
-                                                                typeAnnotations,
-                                                                typeAnnotations,
-                                                                decl);
+                    AnnotatedTypeFactory.nestingForType(types[i], LocationInfo.BASE_LOCATION),
+                    typeAnnotations,
+                    typeAnnotations,
+                    decl);
 
         }
         return result;
@@ -278,7 +275,7 @@
                     }
                 }
                 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
-                        loc,
+                        AnnotatedTypeFactory.nestingForType(bounds[i], loc),
                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
                         candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
                         (AnnotatedElement)decl);
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java	Tue Dec 22 13:41:12 2015 -0800
@@ -39,7 +39,7 @@
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.x509.*;
 import sun.security.util.*;
 
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java	Tue Dec 22 13:41:12 2015 -0800
@@ -38,7 +38,7 @@
 import sun.security.util.DerInputStream;
 import sun.security.util.DerOutputStream;
 import sun.security.util.ObjectIdentifier;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * Class supporting any PKCS9 attributes.
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java	Tue Dec 22 13:41:12 2015 -0800
@@ -41,7 +41,7 @@
 import sun.security.x509.AlgorithmId;
 import sun.security.x509.X500Name;
 import sun.security.x509.KeyUsageExtension;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * A SignerInfo, as defined in PKCS#7's signedData type.
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SigningCertificateInfo.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SigningCertificateInfo.java	Tue Dec 22 13:41:12 2015 -0800
@@ -28,7 +28,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.DerInputStream;
 import sun.security.util.DerValue;
 import sun.security.x509.GeneralNames;
--- a/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java	Tue Dec 22 13:41:12 2015 -0800
@@ -75,7 +75,6 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Random;
-import sun.misc.ManagedLocalsThread;
 import sun.security.util.Debug;
 
 abstract class SeedGenerator {
@@ -305,9 +304,11 @@
                             }
                             finalsg[0] = new ThreadGroup
                                 (group, "SeedGenerator ThreadGroup");
-                            Thread newT = new ManagedLocalsThread(finalsg[0],
+                            Thread newT = new Thread(finalsg[0],
                                 ThreadedSeedGenerator.this,
-                                "SeedGenerator Thread");
+                                "SeedGenerator Thread",
+                                0,
+                                false);
                             newT.setPriority(Thread.MIN_PRIORITY);
                             newT.setDaemon(true);
                             return newT;
@@ -342,8 +343,8 @@
                         // Start some noisy threads
                         try {
                             BogusThread bt = new BogusThread();
-                            Thread t = new ManagedLocalsThread
-                                (seedGroup, bt, "SeedGenerator Thread");
+                            Thread t = new Thread
+                                (seedGroup, bt, "SeedGenerator Thread", 0, false);
                             t.start();
                         } catch (Exception e) {
                             throw new InternalError("internal error: " +
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/CertId.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/CertId.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import javax.security.auth.x500.X500Principal;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.x509.*;
 import sun.security.util.*;
 
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPRequest.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPRequest.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,7 @@
 import java.util.Collections;
 import java.util.List;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 import sun.security.x509.PKIXExtensions;
 
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Tue Dec 22 13:41:12 2015 -0800
@@ -44,7 +44,7 @@
 import java.util.Set;
 import javax.security.auth.x500.X500Principal;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.action.GetIntegerAction;
 import sun.security.x509.*;
 import sun.security.util.*;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java	Tue Dec 22 13:41:12 2015 -0800
@@ -42,7 +42,7 @@
 import static sun.security.ssl.CipherSuite.*;
 import static sun.security.ssl.CipherSuite.CipherType.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -32,7 +32,7 @@
 
 import javax.net.ssl.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import static sun.security.ssl.HandshakeMessage.*;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 
 import javax.net.ssl.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import static sun.security.ssl.Ciphertext.RecordType;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,7 +29,7 @@
 import java.security.AccessController;
 import java.util.Locale;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import java.nio.ByteBuffer;
 
 import sun.security.action.GetPropertyAction;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java	Tue Dec 22 13:41:12 2015 -0800
@@ -41,7 +41,7 @@
 import javax.crypto.spec.*;
 
 import javax.net.ssl.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 import sun.security.internal.spec.*;
 import sun.security.internal.interfaces.TlsMasterSecret;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/InputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/InputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 
 import javax.net.ssl.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/OutputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/OutputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,7 @@
 import java.util.Arrays;
 
 import javax.net.ssl.SSLException;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineInputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineInputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -32,7 +32,7 @@
 
 import javax.net.ssl.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineOutputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineOutputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -31,7 +31,7 @@
 
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import static sun.security.ssl.Ciphertext.RecordType;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -40,7 +40,6 @@
 
 import javax.crypto.BadPaddingException;
 import javax.net.ssl.*;
-import sun.misc.ManagedLocalsThread;
 
 import jdk.internal.misc.JavaNetInetAddressAccess;
 import jdk.internal.misc.SharedSecrets;
@@ -1153,10 +1152,13 @@
                         HandshakeCompletedEvent event =
                             new HandshakeCompletedEvent(this, sess);
 
-                        Thread thread = new ManagedLocalsThread(
+                        Thread thread = new Thread(
+                            null,
                             new NotifyHandshake(
                                 handshakeListeners.entrySet(), event),
-                            "HandshakeCompletedNotify-Thread");
+                            "HandshakeCompletedNotify-Thread",
+                            0,
+                            false);
                         thread.start();
                     }
                 }
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -32,7 +32,7 @@
 
 import javax.net.ssl.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketOutputRecord.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketOutputRecord.java	Tue Dec 22 13:41:12 2015 -0800
@@ -31,7 +31,7 @@
 
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Tue Dec 22 13:41:12 2015 -0800
@@ -2956,7 +2956,7 @@
                 if (v.length == 0) {
                     out.println(rb.getString(".Empty.value."));
                 } else {
-                    new sun.misc.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out);
+                    new sun.security.util.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out);
                     out.println();
                 }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/HexDumpEncoder.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 1995, 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.security.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This class encodes a buffer into the classic: "Hexadecimal Dump" format of
+ * the past. It is useful for analyzing the contents of binary buffers.
+ * The format produced is as follows:
+ * <pre>
+ * xxxx: 00 11 22 33 44 55 66 77   88 99 aa bb cc dd ee ff ................
+ * </pre>
+ * Where xxxx is the offset into the buffer in 16 byte chunks, followed
+ * by ascii coded hexadecimal bytes followed by the ASCII representation of
+ * the bytes or '.' if they are not valid bytes.
+ *
+ * @author      Chuck McManis
+ */
+
+public class HexDumpEncoder {
+
+    private int offset;
+    private int thisLineLength;
+    private int currentByte;
+    private byte thisLine[] = new byte[16];
+
+    static void hexDigit(PrintStream p, byte x) {
+        char c;
+
+        c = (char) ((x >> 4) & 0xf);
+        if (c > 9)
+            c = (char) ((c-10) + 'A');
+        else
+            c = (char)(c + '0');
+        p.write(c);
+        c = (char) (x & 0xf);
+        if (c > 9)
+            c = (char)((c-10) + 'A');
+        else
+            c = (char)(c + '0');
+        p.write(c);
+    }
+
+    protected int bytesPerAtom() {
+        return (1);
+    }
+
+    protected int bytesPerLine() {
+        return (16);
+    }
+
+    protected void encodeBufferPrefix(OutputStream o) throws IOException {
+        offset = 0;
+        pStream = new PrintStream(o);
+    }
+
+    protected void encodeLinePrefix(OutputStream o, int len) throws IOException {
+        hexDigit(pStream, (byte)((offset >>> 8) & 0xff));
+        hexDigit(pStream, (byte)(offset & 0xff));
+        pStream.print(": ");
+        currentByte = 0;
+        thisLineLength = len;
+    }
+
+    protected void encodeAtom(OutputStream o, byte buf[], int off, int len) throws IOException {
+        thisLine[currentByte] = buf[off];
+        hexDigit(pStream, buf[off]);
+        pStream.print(" ");
+        currentByte++;
+        if (currentByte == 8)
+            pStream.print("  ");
+    }
+
+    protected void encodeLineSuffix(OutputStream o) throws IOException {
+        if (thisLineLength < 16) {
+            for (int i = thisLineLength; i < 16; i++) {
+                pStream.print("   ");
+                if (i == 7)
+                    pStream.print("  ");
+            }
+        }
+        pStream.print(" ");
+        for (int i = 0; i < thisLineLength; i++) {
+            if ((thisLine[i] < ' ') || (thisLine[i] > 'z')) {
+                pStream.print(".");
+            } else {
+                pStream.write(thisLine[i]);
+            }
+        }
+        pStream.println();
+        offset += thisLineLength;
+    }
+
+    /** Stream that understands "printing" */
+    protected PrintStream pStream;
+
+    /**
+     * This method works around the bizarre semantics of BufferedInputStream's
+     * read method.
+     */
+    protected int readFully(InputStream in, byte buffer[])
+            throws java.io.IOException {
+        for (int i = 0; i < buffer.length; i++) {
+            int q = in.read();
+            if (q == -1)
+                return i;
+            buffer[i] = (byte)q;
+        }
+        return buffer.length;
+    }
+
+    /**
+     * Encode bytes from the input stream, and write them as text characters
+     * to the output stream. This method will run until it exhausts the
+     * input stream, but does not print the line suffix for a final
+     * line that is shorter than bytesPerLine().
+     */
+    public void encode(InputStream inStream, OutputStream outStream)
+        throws IOException
+    {
+        int     j;
+        int     numBytes;
+        byte    tmpbuffer[] = new byte[bytesPerLine()];
+
+        encodeBufferPrefix(outStream);
+
+        while (true) {
+            numBytes = readFully(inStream, tmpbuffer);
+            if (numBytes == 0) {
+                break;
+            }
+            encodeLinePrefix(outStream, numBytes);
+            for (j = 0; j < numBytes; j += bytesPerAtom()) {
+
+                if ((j + bytesPerAtom()) <= numBytes) {
+                    encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
+                } else {
+                    encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
+                }
+            }
+            if (numBytes < bytesPerLine()) {
+                break;
+            } else {
+                encodeLineSuffix(outStream);
+            }
+        }
+    }
+
+    /**
+     * A 'streamless' version of encode that simply takes a buffer of
+     * bytes and returns a string containing the encoded buffer.
+     */
+    public String encode(byte aBuffer[]) {
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        ByteArrayInputStream    inStream = new ByteArrayInputStream(aBuffer);
+        String retVal = null;
+        try {
+            encode(inStream, outStream);
+            // explicit ascii->unicode conversion
+            retVal = outStream.toString("ISO-8859-1");
+        } catch (Exception IOException) {
+            // This should never happen.
+            throw new Error("CharacterEncoder.encode internal error");
+        }
+        return (retVal);
+    }
+
+    /**
+     * Return a byte array from the remaining bytes in this ByteBuffer.
+     * <P>
+     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+     * <P>
+     * To avoid an extra copy, the implementation will attempt to return the
+     * byte array backing the ByteBuffer.  If this is not possible, a
+     * new byte array will be created.
+     */
+    private byte [] getBytes(ByteBuffer bb) {
+        /*
+         * This should never return a BufferOverflowException, as we're
+         * careful to allocate just the right amount.
+         */
+        byte [] buf = null;
+
+        /*
+         * If it has a usable backing byte buffer, use it.  Use only
+         * if the array exactly represents the current ByteBuffer.
+         */
+        if (bb.hasArray()) {
+            byte [] tmp = bb.array();
+            if ((tmp.length == bb.capacity()) &&
+                    (tmp.length == bb.remaining())) {
+                buf = tmp;
+                bb.position(bb.limit());
+            }
+        }
+
+        if (buf == null) {
+            /*
+             * This class doesn't have a concept of encode(buf, len, off),
+             * so if we have a partial buffer, we must reallocate
+             * space.
+             */
+            buf = new byte[bb.remaining()];
+
+            /*
+             * position() automatically updated
+             */
+            bb.get(buf);
+        }
+
+        return buf;
+    }
+
+    /**
+     * A 'streamless' version of encode that simply takes a ByteBuffer
+     * and returns a string containing the encoded buffer.
+     * <P>
+     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+     */
+    public String encode(ByteBuffer aBuffer) {
+        byte [] buf = getBytes(aBuffer);
+        return encode(buf);
+    }
+
+    /**
+     * Encode bytes from the input stream, and write them as text characters
+     * to the output stream. This method will run until it exhausts the
+     * input stream. It differs from encode in that it will add the
+     * line at the end of a final line that is shorter than bytesPerLine().
+     */
+    public void encodeBuffer(InputStream inStream, OutputStream outStream)
+        throws IOException
+    {
+        int     j;
+        int     numBytes;
+        byte    tmpbuffer[] = new byte[bytesPerLine()];
+
+        encodeBufferPrefix(outStream);
+
+        while (true) {
+            numBytes = readFully(inStream, tmpbuffer);
+            if (numBytes == 0) {
+                break;
+            }
+            encodeLinePrefix(outStream, numBytes);
+            for (j = 0; j < numBytes; j += bytesPerAtom()) {
+                if ((j + bytesPerAtom()) <= numBytes) {
+                    encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
+                } else {
+                    encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
+                }
+            }
+            encodeLineSuffix(outStream);
+            if (numBytes < bytesPerLine()) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Encode the buffer in <i>aBuffer</i> and write the encoded
+     * result to the OutputStream <i>aStream</i>.
+     */
+    public void encodeBuffer(byte aBuffer[], OutputStream aStream)
+        throws IOException
+    {
+        ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+        encodeBuffer(inStream, aStream);
+    }
+
+    /**
+     * A 'streamless' version of encode that simply takes a buffer of
+     * bytes and returns a string containing the encoded buffer.
+     */
+    public String encodeBuffer(byte aBuffer[]) {
+        ByteArrayOutputStream   outStream = new ByteArrayOutputStream();
+        ByteArrayInputStream    inStream = new ByteArrayInputStream(aBuffer);
+        try {
+            encodeBuffer(inStream, outStream);
+        } catch (Exception IOException) {
+            // This should never happen.
+            throw new Error("CharacterEncoder.encodeBuffer internal error");
+        }
+        return (outStream.toString());
+    }
+
+    /**
+     * Encode the <i>aBuffer</i> ByteBuffer and write the encoded
+     * result to the OutputStream <i>aStream</i>.
+     * <P>
+     * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+     */
+    public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
+        throws IOException
+    {
+        byte [] buf = getBytes(aBuffer);
+        encodeBuffer(buf, aStream);
+    }
+
+}
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Tue Dec 22 13:41:12 2015 -0800
@@ -443,7 +443,7 @@
 
         if (sfAttr != null) {
 
-            //sun.misc.HexDumpEncoder hex = new sun.misc.HexDumpEncoder();
+            //sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
             //hex.encodeBuffer(data, System.out);
 
             // go through all the attributes and process *-Digest entries
--- a/jdk/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 import java.security.cert.CertificateException;
 import java.util.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 import sun.security.util.*;
 
@@ -376,6 +376,6 @@
     @Override public String toString() {
         return super.toString() +
                 "Unparseable " + name + "extension due to\n" + why + "\n\n" +
-                new sun.misc.HexDumpEncoder().encodeBuffer(getExtensionValue());
+                new HexDumpEncoder().encodeBuffer(getExtensionValue());
     }
 }
--- a/jdk/src/java.base/share/classes/sun/security/x509/IPAddressName.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/IPAddressName.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,7 +29,7 @@
 import java.lang.Integer;
 import java.net.InetAddress;
 import java.util.Arrays;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.BitArray;
 import sun.security.util.DerOutputStream;
 import sun.security.util.DerValue;
--- a/jdk/src/java.base/share/classes/sun/security/x509/KeyIdentifier.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/KeyIdentifier.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,7 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/x509/UniqueIdentity.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/UniqueIdentity.java	Tue Dec 22 13:41:12 2015 -0800
@@ -27,7 +27,7 @@
 import java.io.IOException;
 import java.math.BigInteger;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -35,7 +35,7 @@
 import javax.security.auth.x500.X500Principal;
 
 import sun.security.util.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * <p>Abstract class for a revoked certificate in a CRL.
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -49,7 +49,7 @@
 
 import sun.security.provider.X509Factory;
 import sun.security.util.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * <p>
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -41,7 +41,7 @@
 
 import javax.security.auth.x500.X500Principal;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import java.util.Base64;
 import sun.security.util.*;
 import sun.security.provider.X509Factory;
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CertInfo.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CertInfo.java	Tue Dec 22 13:41:12 2015 -0800
@@ -32,7 +32,7 @@
 import java.util.*;
 
 import sun.security.util.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509Key.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509Key.java	Tue Dec 22 13:41:12 2015 -0800
@@ -38,7 +38,7 @@
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.X509EncodedKeySpec;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.util.*;
 
 /**
--- a/jdk/src/java.base/share/native/libzip/ZipFile.c	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,406 +0,0 @@
-/*
- * Copyright (c) 1998, 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.
- */
-
-/*
- * Native method support for java.util.zip.ZipFile
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <assert.h>
-#include "jlong.h"
-#include "jvm.h"
-#include "jni.h"
-#include "jni_util.h"
-#include "zip_util.h"
-#ifdef WIN32
-#include "io_util_md.h"
-#else
-#include "io_util.h"
-#endif
-
-#include "java_util_zip_ZipFile.h"
-#include "java_util_jar_JarFile.h"
-
-#define DEFLATED 8
-#define STORED 0
-
-static jfieldID jzfileID;
-
-static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
-static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
-
-
-/*
- * Declare library specific JNI_Onload entry if static build
- */
-DEF_STATIC_JNI_OnLoad
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
-{
-    jzfileID = (*env)->GetFieldID(env, cls, "jzfile", "J");
-    assert(jzfileID != 0);
-}
-
-static void
-ThrowZipException(JNIEnv *env, const char *msg)
-{
-    jstring s = NULL;
-    jobject x;
-
-    if (msg != NULL) {
-        s = JNU_NewStringPlatform(env, msg);
-    }
-    if (s != NULL) {
-        x = JNU_NewObjectByName(env,
-                            "java/util/zip/ZipException",
-                            "(Ljava/lang/String;)V", s);
-        if (x != NULL) {
-            (*env)->Throw(env, x);
-        }
-    }
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
-                                        jint mode, jlong lastModified,
-                                        jboolean usemmap)
-{
-    const char *path = JNU_GetStringPlatformChars(env, name, 0);
-    char *msg = 0;
-    jlong result = 0;
-    int flag = 0;
-    jzfile *zip = 0;
-
-    if (mode & OPEN_READ) flag |= O_RDONLY;
-
-    if (path != 0) {
-        zip = ZIP_Get_From_Cache(path, &msg, lastModified);
-        if (zip == 0 && msg == 0) {
-            ZFILE zfd = 0;
-#ifdef WIN32
-            if (mode & OPEN_DELETE) flag |= O_TEMPORARY;
-            zfd = winFileHandleOpen(env, name, flag);
-            if (zfd == -1) {
-                /* Exception already pending. */
-                goto finally;
-            }
-#else
-            zfd = open(path, flag, 0);
-            if (zfd < 0) {
-                throwFileNotFoundException(env, name);
-                goto finally;
-            }
-            if (mode & OPEN_DELETE) {
-                unlink(path);
-            }
-#endif
-            zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);
-        }
-
-        if (zip != 0) {
-            result = ptr_to_jlong(zip);
-        } else if (msg != 0) {
-            ThrowZipException(env, msg);
-            free(msg);
-        } else if (errno == ENOMEM) {
-            JNU_ThrowOutOfMemoryError(env, 0);
-        } else {
-            ThrowZipException(env, "error in opening zip file");
-        }
-finally:
-        JNU_ReleaseStringPlatformChars(env, name, path);
-    }
-    return result;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-
-    return zip->total;
-}
-
-JNIEXPORT jboolean JNICALL
-Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-
-    return zip->locsig;
-}
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
-{
-    ZIP_Close(jlong_to_ptr(zfile));
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
-                                    jbyteArray name, jboolean addSlash)
-{
-#define MAXNAME 1024
-    jzfile *zip = jlong_to_ptr(zfile);
-    jsize ulen = (*env)->GetArrayLength(env, name);
-    char buf[MAXNAME+2], *path;
-    jzentry *ze;
-
-    if (ulen > MAXNAME) {
-        path = malloc(ulen + 2);
-        if (path == 0) {
-            JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
-    } else {
-        path = buf;
-    }
-    (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
-    path[ulen] = '\0';
-    ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
-    if (path != buf) {
-        free(path);
-    }
-    return ptr_to_jlong(ze);
-}
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,
-                                    jlong zentry)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    jzentry *ze = jlong_to_ptr(zentry);
-    ZIP_FreeEntry(zip, ze);
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,
-                                        jint n)
-{
-    jzentry *ze = ZIP_GetNextEntry(jlong_to_ptr(zfile), n);
-    return ptr_to_jlong(ze);
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_getEntryMethod(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->csize != 0 ? DEFLATED : STORED;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_getEntryFlag(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->flag;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntryCSize(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->csize != 0 ? ze->csize : ze->size;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntrySize(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->size;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntryTime(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return (jlong)ze->time & 0xffffffffUL;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntryCrc(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return (jlong)ze->crc & 0xffffffffUL;
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_java_util_zip_ZipFile_getCommentBytes(JNIEnv *env,
-                                           jclass cls,
-                                           jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    jbyteArray jba = NULL;
-
-    if (zip->comment != NULL) {
-        if ((jba = (*env)->NewByteArray(env, zip->clen)) == NULL)
-            return NULL;
-        (*env)->SetByteArrayRegion(env, jba, 0, zip->clen, (jbyte*)zip->comment);
-    }
-    return jba;
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
-                                         jclass cls,
-                                         jlong zentry, jint type)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    int len = 0;
-    jbyteArray jba = NULL;
-    switch (type) {
-    case java_util_zip_ZipFile_JZENTRY_NAME:
-        if (ze->name != 0) {
-            len = (int)ze->nlen;
-            // Unlike for extra and comment, we never return null for
-            // an (extremely rarely seen) empty name
-            if ((jba = (*env)->NewByteArray(env, len)) == NULL)
-                break;
-            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
-        }
-        break;
-    case java_util_zip_ZipFile_JZENTRY_EXTRA:
-        if (ze->extra != 0) {
-            unsigned char *bp = (unsigned char *)&ze->extra[0];
-            len = (bp[0] | (bp[1] << 8));
-            if (len <= 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
-                break;
-            (*env)->SetByteArrayRegion(env, jba, 0, len, &ze->extra[2]);
-        }
-        break;
-    case java_util_zip_ZipFile_JZENTRY_COMMENT:
-        if (ze->comment != 0) {
-            len = (int)strlen(ze->comment);
-            if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
-                break;
-            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte*)ze->comment);
-        }
-        break;
-    }
-    return jba;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,
-                                jlong zentry, jlong pos, jbyteArray bytes,
-                                jint off, jint len)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    char *msg;
-
-#define BUFSIZE 8192
-    /* copy via tmp stack buffer: */
-    jbyte buf[BUFSIZE];
-
-    if (len > BUFSIZE) {
-        len = BUFSIZE;
-    }
-
-    ZIP_Lock(zip);
-    len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);
-    msg = zip->msg;
-    ZIP_Unlock(zip);
-    if (len != -1) {
-        (*env)->SetByteArrayRegion(env, bytes, off, len, buf);
-    }
-
-    if (len == -1) {
-        if (msg != 0) {
-            ThrowZipException(env, msg);
-        } else {
-            char errmsg[128];
-            sprintf(errmsg, "errno: %d, error: %s\n",
-                    errno, "Error reading ZIP file");
-            JNU_ThrowIOExceptionWithLastError(env, errmsg);
-        }
-    }
-
-    return len;
-}
-
-/*
- * Returns an array of strings representing the names of all entries
- * that begin with "META-INF/" (case ignored). This native method is
- * used in JarFile as an optimization when looking up manifest and
- * signature file entries. Returns null if no entries were found.
- */
-JNIEXPORT jobjectArray JNICALL
-Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)
-{
-    jlong zfile = (*env)->GetLongField(env, obj, jzfileID);
-    jzfile *zip;
-    int i, count;
-    jobjectArray result = 0;
-
-    if (zfile == 0) {
-        JNU_ThrowByName(env,
-                        "java/lang/IllegalStateException", "zip file closed");
-        return NULL;
-    }
-    zip = jlong_to_ptr(zfile);
-
-    /* count the number of valid ZIP metanames */
-    count = 0;
-    if (zip->metanames != 0) {
-        for (i = 0; i < zip->metacount; i++) {
-            if (zip->metanames[i] != 0) {
-                count++;
-            }
-        }
-    }
-
-    /* If some names were found then build array of java strings */
-    if (count > 0) {
-        jclass cls = JNU_ClassString(env);
-        CHECK_NULL_RETURN(cls, NULL);
-        result = (*env)->NewObjectArray(env, count, cls, 0);
-        CHECK_NULL_RETURN(result, NULL);
-        if (result != 0) {
-            for (i = 0; i < count; i++) {
-                jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);
-                if (str == 0) {
-                    break;
-                }
-                (*env)->SetObjectArrayElement(env, result, i, str);
-                (*env)->DeleteLocalRef(env, str);
-            }
-        }
-    }
-    return result;
-}
-
-JNIEXPORT jstring JNICALL
-Java_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    char *msg = zip->msg;
-    if (msg == NULL) {
-        return NULL;
-    }
-    return JNU_NewStringPlatform(env, msg);
-}
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -40,7 +40,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * A multi-threaded implementation of Selector for Windows.
@@ -404,13 +403,14 @@
     }
 
     // Represents a helper thread used for select.
-    private final class SelectThread extends ManagedLocalsThread {
+    private final class SelectThread extends Thread {
         private final int index; // index of this thread
         final SubSelector subSelector;
         private long lastRun = 0; // last run number
         private volatile boolean zombie;
         // Creates a new thread
         private SelectThread(int i) {
+            super(null, null, "SelectorHelper", 0, false);
             this.index = i;
             this.subSelector = new SubSelector(i);
             //make sure we wait for next round of poll
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Tue Dec 22 13:41:12 2015 -0800
@@ -38,6 +38,7 @@
 import java.security.*;
 import java.util.*;
 import java.util.Locale;
+import java.util.concurrent.LinkedBlockingQueue;
 import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
 import sun.awt.EmbeddedFrame;
@@ -45,7 +46,6 @@
 import sun.misc.ManagedLocalsThread;
 import sun.misc.MessageUtils;
 import sun.misc.PerformanceLogger;
-import sun.misc.Queue;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -247,8 +247,7 @@
     /**
      * AppletEvent Queue
      */
-    private Queue<Integer> queue = null;
-
+    private LinkedBlockingQueue<Integer> queue = null;
 
     public synchronized void addAppletListener(AppletListener l) {
         listeners = AppletEventMulticaster.add(listeners, l);
@@ -276,10 +275,9 @@
         synchronized(this) {
             if (queue == null) {
                 //System.out.println("SEND0= " + id);
-                queue = new Queue<>();
+                queue = new LinkedBlockingQueue<>();
             }
-            Integer eventId = Integer.valueOf(id);
-            queue.enqueue(eventId);
+            boolean inserted = queue.add(id);
             notifyAll();
         }
         if (id == APPLET_QUIT) {
@@ -303,8 +301,8 @@
         while (queue == null || queue.isEmpty()) {
             wait();
         }
-        Integer eventId = queue.dequeue();
-        return new AppletEvent(this, eventId.intValue(), null);
+        int eventId = queue.take();
+        return new AppletEvent(this, eventId, null);
     }
 
     boolean emptyEventQueue() {
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java	Tue Dec 22 13:41:12 2015 -0800
@@ -156,8 +156,6 @@
                     // rewritten to avoid division:
                     || (width * heightSubPixel) >
                             ((edgeSumDeltaY - heightSubPixel) << BLOCK_SIZE_LG);
-//                            ((edgeSumDeltaY - heightSubPixel) * RLE_THRESHOLD);
-//                            ((edgeSumDeltaY - heightSubPixel) << BLOCK_TH_LG);
 
                 if (doTrace && !useRLE) {
                     final float meanCrossings
@@ -293,8 +291,10 @@
         // update row index to current position:
         rowAAChunkIndex[row] = pos;
 
-        // determine need array size (may overflow):
-        final long needSize = pos + (px_bbox1 - px0);
+        // determine need array size:
+        // for RLE encoding, position must be aligned to 4 bytes (int):
+        // align - 1 = 3 so add +3 and round-off by mask ~3 = -4
+        final long needSize = pos + ((px_bbox1 - px0 + 3) & -4);
 
         // update next position (bytes):
         rowAAChunkPos = needSize;
@@ -401,8 +401,7 @@
 
         // determine need array size:
         // pessimistic: max needed size = deltaX x 4 (1 int)
-        final int maxLen = (to - from);
-        final long needSize = initialPos + (maxLen << 2);
+        final long needSize = initialPos + ((to - from) << 2);
 
         // update row data:
         OffHeapArray _rowAAChunk = rowAAChunk;
@@ -465,6 +464,13 @@
                             // note: last pixel exclusive (>= 0)
                             // note: it should check X is smaller than 23bits (overflow)!
 
+                            // check address alignment to 4 bytes:
+                            if (doCheckUnsafe) {
+                                if ((addr_off & 3) != 0) {
+                                    MarlinUtils.logInfo("Misaligned Unsafe address: " + addr_off);
+                                }
+                            }
+
                             // special case to encode entries into a single int:
                             if (val == 0) {
                                 _unsafe.putInt(addr_off,
@@ -521,6 +527,13 @@
         // note: last pixel exclusive (>= 0)
         // note: it should check X is smaller than 23bits (overflow)!
 
+        // check address alignment to 4 bytes:
+        if (doCheckUnsafe) {
+            if ((addr_off & 3) != 0) {
+                MarlinUtils.logInfo("Misaligned Unsafe address: " + addr_off);
+            }
+        }
+
         // special case to encode entries into a single int:
         if (val == 0) {
             _unsafe.putInt(addr_off,
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java	Tue Dec 22 13:41:12 2015 -0800
@@ -40,6 +40,8 @@
     // log misc.Unsafe alloc/realloc/free
     static final boolean logUnsafeMalloc = enableLogs
         && MarlinProperties.isLogUnsafeMalloc();
+    // do check unsafe alignment:
+    static final boolean doCheckUnsafe = false;
 
     // do statistics
     static final boolean doStats = enableLogs && MarlinProperties.isDoStats();
--- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/Ber.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/Ber.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,7 +29,7 @@
 import java.io.IOException;
 import java.io.ByteArrayInputStream;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
   * Base class that defines common fields, constants, and debug method.
--- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -44,7 +44,7 @@
 import javax.naming.ldap.LdapContext;
 import javax.security.auth.x500.X500Principal;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.provider.certpath.X509CertificatePair;
 import sun.security.util.Cache;
 import sun.security.util.Debug;
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Tue Dec 22 13:41:12 2015 -0800
@@ -34,7 +34,7 @@
 import javax.security.auth.Destroyable;
 import javax.security.auth.RefreshFailedException;
 import javax.security.auth.DestroyFailedException;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * This class encapsulates a Kerberos ticket and associated
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,7 +30,7 @@
 import javax.crypto.SecretKey;
 import javax.security.auth.Destroyable;
 import javax.security.auth.DestroyFailedException;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.krb5.Asn1Exception;
 import sun.security.krb5.PrincipalName;
 import sun.security.krb5.EncryptionKey;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Tue Dec 22 13:41:12 2015 -0800
@@ -26,7 +26,7 @@
 package sun.security.jgss.krb5;
 
 import org.ietf.jgss.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.jgss.GSSUtil;
 import sun.security.jgss.GSSCaller;
 import sun.security.jgss.spi.*;
@@ -1415,7 +1415,7 @@
         @Override
         public String toString() {
             return "Kerberos session key: etype: " + key.getEType() + "\n" +
-                    new sun.misc.HexDumpEncoder().encodeBuffer(key.getBytes());
+                    new HexDumpEncoder().encodeBuffer(key.getBytes());
         }
     }
 
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/KRBError.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/KRBError.java	Tue Dec 22 13:41:12 2015 -0800
@@ -227,7 +227,7 @@
             } catch (Exception e) {
                 if (DEBUG) {
                     System.out.println("Unable to parse eData field of KRB-ERROR:\n" +
-                            new sun.misc.HexDumpEncoder().encodeBuffer(data));
+                            new sun.security.util.HexDumpEncoder().encodeBuffer(data));
                 }
                 IOException ioe = new IOException(
                         "Unable to parse eData field of KRB-ERROR");
@@ -237,7 +237,7 @@
         } else {
             if (DEBUG) {
                 System.out.println("Unknown eData field of KRB-ERROR:\n" +
-                        new sun.misc.HexDumpEncoder().encodeBuffer(data));
+                        new sun.security.util.HexDumpEncoder().encodeBuffer(data));
             }
         }
     }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java	Tue Dec 22 13:41:12 2015 -0800
@@ -306,8 +306,8 @@
     public static final boolean DEBUG =
         java.security.AccessController.doPrivileged(
               new sun.security.action.GetBooleanAction("sun.security.krb5.debug"));
-    public static final sun.misc.HexDumpEncoder hexDumper =
-        new sun.misc.HexDumpEncoder();
+    public static final sun.security.util.HexDumpEncoder hexDumper =
+        new sun.security.util.HexDumpEncoder();
 
     static {
         errMsgList = new Hashtable<Integer,String> ();
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java	Tue Dec 22 13:41:12 2015 -0800
@@ -306,7 +306,7 @@
                             } else if (s2kparams.length == 0) {
                                 sb.append("empty\n");
                             } else {
-                                sb.append(new sun.misc.HexDumpEncoder()
+                                sb.append(new sun.security.util.HexDumpEncoder()
                                         .encodeBuffer(s2kparams));
                             }
                         }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/dk/DkCrypto.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/dk/DkCrypto.java	Tue Dec 22 13:41:12 2015 -0800
@@ -40,7 +40,7 @@
 import java.nio.charset.Charset;
 import java.nio.CharBuffer;
 import java.nio.ByteBuffer;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.krb5.Confounder;
 import sun.security.krb5.internal.crypto.KeyUsage;
 import sun.security.krb5.KrbCryptoException;
--- a/jdk/src/java.security.sasl/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/java.security.sasl/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 import java.util.logging.Logger;
 import java.util.logging.Level;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * The base class used by client and server implementations of SASL
--- a/jdk/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java	Tue Dec 22 13:41:12 2015 -0800
@@ -44,7 +44,7 @@
 import sun.security.krb5.*;
 import sun.security.jgss.krb5.Krb5Util;
 import sun.security.krb5.Credentials;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * This {@code LoginModule} authenticates users using
--- a/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java	Tue Dec 22 13:41:12 2015 -0800
@@ -64,6 +64,6 @@
     public String toString() {
         return "AuthorizationDataEntry: type="+type+", data=" +
                 data.length + " bytes:\n" +
-                new sun.misc.HexDumpEncoder().encodeBuffer(data);
+                new sun.security.util.HexDumpEncoder().encodeBuffer(data);
     }
 }
--- a/jdk/test/TEST.groups	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/TEST.groups	Tue Dec 22 13:41:12 2015 -0800
@@ -95,16 +95,19 @@
     -:jdk_concurrent \
     -:jdk_stream
 
-# java.util.concurrent (JSR-166)
+# All collections, core and concurrent
+jdk_collections = \
+    :jdk_collections_core \
+    :jdk_concurrent
+
+# java.util.concurrent
+# Includes concurrent collections plus other stuff
 # Maintained by JSR-166 EG (Doug Lea et al)
-# Deque and PriorityQueue are also generally maintained by JSR-166
 jdk_concurrent = \
-    java/util/concurrent \
-    java/util/Deque \
-    java/util/PriorityQueue
+    java/util/concurrent
 
-# Java Collections Framework
-jdk_collections = \
+# Java Collections Framework core classes
+jdk_collections_core = \
     java/util/AbstractCollection \
     java/util/AbstractList \
     java/util/AbstractMap \
@@ -114,19 +117,22 @@
     java/util/BitSet \
     java/util/Collection \
     java/util/Collections \
+    java/util/Comparator \
+    java/util/Deque \
     java/util/EnumMap \
     java/util/EnumSet \
-    java/util/Comparator \
-    java/util/Iterator \
     java/util/HashMap \
+    java/util/HashSet \
     java/util/Hashtable \
     java/util/IdentityHashMap \
-    java/util/List \
+    java/util/Iterator \
     java/util/LinkedHashMap \
     java/util/LinkedHashSet \
     java/util/LinkedList \
+    java/util/List \
     java/util/Map \
     java/util/NavigableMap \
+    java/util/PriorityQueue \
     java/util/TimSort \
     java/util/TreeMap \
     java/util/Vector \
--- a/jdk/test/com/oracle/security/ucrypto/TestCICOWithGCMAndAAD.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/com/oracle/security/ucrypto/TestCICOWithGCMAndAAD.java	Tue Dec 22 13:41:12 2015 -0800
@@ -65,7 +65,10 @@
         byte[] aad2 = aad.clone();
         aad2[50]++;
 
-        GCMParameterSpec spec = new GCMParameterSpec(128, new byte[16]);
+        byte[] iv = new byte[16];
+        rdm.nextBytes(iv);
+
+        GCMParameterSpec spec = new GCMParameterSpec(128, iv);
         Cipher encCipher = Cipher.getInstance("AES/GCM/NoPadding", p);
         encCipher.init(Cipher.ENCRYPT_MODE, key, spec);
         encCipher.updateAAD(aad);
--- a/jdk/test/com/oracle/security/ucrypto/TestGCMKeyAndIvCheck.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/com/oracle/security/ucrypto/TestGCMKeyAndIvCheck.java	Tue Dec 22 13:41:12 2015 -0800
@@ -126,7 +126,11 @@
         }
 
         // Now try to encrypt again using a different parameter; should work
-        c.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, new byte[30]));
+        byte[] rdm_iv = new byte[30];
+        Random rdm = new Random();
+        rdm.nextBytes(rdm_iv);
+
+        c.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, rdm_iv));
         c.updateAAD(AAD);
         c.doFinal(PT);
         // subsequent encryption should fail unless re-init w/ different key+iv
--- a/jdk/test/com/sun/crypto/provider/KeyAgreement/DHKeyAgreement2.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/com/sun/crypto/provider/KeyAgreement/DHKeyAgreement2.java	Tue Dec 22 13:41:12 2015 -0800
@@ -25,7 +25,6 @@
  * @test
  * @bug 7146728
  * @summary DHKeyAgreement2
- * @modules java.base/sun.misc
  * @author Jan Luehe
  */
 
@@ -38,8 +37,6 @@
 import javax.crypto.spec.*;
 import javax.crypto.interfaces.*;
 
-import sun.misc.HexDumpEncoder;
-
 /**
  * This test utility executes the Diffie-Hellman key agreement protocol
  * between 2 parties: Alice and Bob.
--- a/jdk/test/com/sun/jndi/ldap/Base64Test.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/com/sun/jndi/ldap/Base64Test.java	Tue Dec 22 13:41:12 2015 -0800
@@ -164,7 +164,7 @@
     private static void deserialize(byte[] bytes) throws Exception {
 
         //System.out.println("\nSerialized RefAddr object: ");
-        //System.out.println(new sun.misc.HexDumpEncoder().encode(bytes));
+        //System.out.println(new sun.security.util.HexDumpEncoder().encode(bytes));
 
         ObjectInputStream objectStream =
             new ObjectInputStream(new ByteArrayInputStream(bytes));
--- a/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java	Tue Dec 22 13:41:12 2015 -0800
@@ -25,13 +25,14 @@
  * @test
  * @bug 6911951 7150092
  * @summary NTLM should be a supported Java SASL mechanism
- * @modules java.base/sun.misc
+ * @modules java.base/sun.security.util
  *          java.security.sasl
  */
 import java.io.IOException;
 import javax.security.sasl.*;
 import javax.security.auth.callback.*;
 import java.util.*;
+import sun.security.util.HexDumpEncoder;
 
 public class NTLMTest {
 
@@ -311,7 +312,7 @@
         byte[] response = (clnt.hasInitialResponse()
                 ? clnt.evaluateChallenge(EMPTY) : EMPTY);
         System.out.println("Initial:");
-        new sun.misc.HexDumpEncoder().encodeBuffer(response, System.out);
+        new HexDumpEncoder().encodeBuffer(response, System.out);
         byte[] challenge;
 
         while (!clnt.isComplete() || !srv.isComplete()) {
@@ -319,12 +320,12 @@
             response = null;
             if (challenge != null) {
                 System.out.println("Challenge:");
-                new sun.misc.HexDumpEncoder().encodeBuffer(challenge, System.out);
+                new HexDumpEncoder().encodeBuffer(challenge, System.out);
                 response = clnt.evaluateChallenge(challenge);
             }
             if (response != null) {
                 System.out.println("Response:");
-                new sun.misc.HexDumpEncoder().encodeBuffer(response, System.out);
+                new HexDumpEncoder().encodeBuffer(response, System.out);
             }
         }
 
--- a/jdk/test/java/beans/EventHandler/Test6277246.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/beans/EventHandler/Test6277246.java	Tue Dec 22 13:41:12 2015 -0800
@@ -39,7 +39,7 @@
             Class container = Class.forName("java.lang.Class");
             Class parameter = Class.forName("java.lang.String");
             Method method = container.getMethod("forName", parameter);
-            Object[] arglist = new Object[] {"sun.misc.BASE64Encoder"};
+            Object[] arglist = new Object[] {"sun.security.x509.X509CertInfo"};
             EventHandler eh = new EventHandler(Test6277246.class, "forName", "", "forName");
             Object object = eh.invoke(null, method, arglist);
             throw new Error((object != null) ? "test failure" : "test error");
--- a/jdk/test/java/beans/Introspector/Test6277246.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/beans/Introspector/Test6277246.java	Tue Dec 22 13:41:12 2015 -0800
@@ -25,7 +25,7 @@
  * @test
  * @bug 6277246
  * @summary Tests problem with java.beans use of reflection
- * @modules java.base/sun.misc
+ * @modules java.base/sun.security.x509
  *          java.desktop
  * @run main/othervm Test6277246
  * @author Jeff Nisewanger
@@ -36,11 +36,10 @@
 import java.beans.Introspector;
 import java.beans.MethodDescriptor;
 import java.lang.reflect.Method;
-import sun.misc.BASE64Encoder;
 
 public class Test6277246 {
     public static void main(String[] args) throws IntrospectionException {
-        Class type = BASE64Encoder.class;
+        Class type = sun.security.x509.X509CertInfo.class;
         System.setSecurityManager(new SecurityManager());
         BeanInfo info = Introspector.getBeanInfo(type);
         for (MethodDescriptor md : info.getMethodDescriptors()) {
@@ -48,7 +47,7 @@
             System.out.println(method);
 
             String name = method.getDeclaringClass().getName();
-            if (name.startsWith("sun.misc.")) {
+            if (name.startsWith("sun.")) {
                 throw new Error("found inaccessible method");
             }
         }
--- a/jdk/test/java/beans/Statement/Test6224433.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/beans/Statement/Test6224433.java	Tue Dec 22 13:41:12 2015 -0800
@@ -36,7 +36,7 @@
             System.setSecurityManager(new SecurityManager());
             Class target = Test6224433.class;
             String method = "forName";
-            String[] params = {"sun.misc.BASE64Encoder"};
+            String[] params = {"sun.security.x509.X509CertInfo"};
             if (null != new Expression(target, method, params).getValue())
                 throw new Error("failure: bug exists");
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/PushbackReader/ReadCloseRaceNPE.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8143394
+ * @summary Check for NullPointerException in race between read() and close().
+ */
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
+
+public class ReadCloseRaceNPE {
+
+    private static final int BUF_SIZE = 1000;
+    private static final long TIMEOUT_MS = 3000;
+
+    private static final List<Exception> failures = new ArrayList<>();
+
+    private static void testReader(final Supplier<Reader> readerSupplier)
+            throws InterruptedException {
+        AtomicReference<Reader> readerRef =
+            new AtomicReference<>(readerSupplier.get());
+
+        AtomicBoolean isFinished = new AtomicBoolean();
+
+        Runnable readTask = () -> {
+            long startTime = System.currentTimeMillis();
+            while (System.currentTimeMillis() - startTime < TIMEOUT_MS) {
+                try {
+                    readerRef.get().read();
+                } catch (Exception e) {
+                    if (!(e instanceof IOException)) {
+                        failures.add(e);
+                        break;
+                    }
+                    readerRef.set(readerSupplier.get());
+                }
+            }
+            isFinished.set(true);
+        };
+
+        Runnable closeTask = () -> {
+            while (!isFinished.get()) {
+                try {
+                    readerRef.get().close();
+                } catch (Exception e) {
+                    if (!(e instanceof IOException)) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        };
+
+        Thread readThread = new Thread(readTask);
+        Thread closeThread = new Thread(closeTask);
+
+        readThread.start();
+        closeThread.start();
+        readThread.join();
+        closeThread.join();
+    }
+
+    public static void main(String[] args) throws Throwable {
+        final String s = "Two riders were approaching.\\n";
+
+        Supplier<Reader> charPushbackReaderSupplier = () -> {
+            char buf[] = new char[s.length()];
+            s.getChars(0, s.length(), buf, 0);
+            CharArrayReader in = new CharArrayReader(buf);
+            return new PushbackReader(in, BUF_SIZE);
+        };
+
+        testReader(charPushbackReaderSupplier);
+
+        Supplier<Reader> stringPushbackReaderSupplier = () -> {
+            StringReader in = new StringReader(s);
+            return new PushbackReader(in, BUF_SIZE);
+        };
+
+        testReader(stringPushbackReaderSupplier);
+
+        if (!failures.isEmpty()) {
+            failures.stream().forEach((x) -> ((Exception) x).printStackTrace());
+            throw new RuntimeException("PushbackReaderNPE failed");
+        }
+    }
+}
--- a/jdk/test/java/lang/StackWalker/MultiThreadStackWalk.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/lang/StackWalker/MultiThreadStackWalk.java	Tue Dec 22 13:41:12 2015 -0800
@@ -328,7 +328,7 @@
 
         public void run() {
             try {
-                Env env = runTest(test, 2000, 10);
+                Env env = runTest(test, 1000, 10);
                 //waitWalkers(env);
                 checkTest(env, test);
             } catch(Throwable t) {
--- a/jdk/test/java/lang/StackWalker/StackWalkTest.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/lang/StackWalker/StackWalkTest.java	Tue Dec 22 13:41:12 2015 -0800
@@ -236,6 +236,8 @@
         if (didWalk) {
             throw new IllegalStateException("StackWalkTest already used");
         }
+        // Test may run into StackOverflow when running in -Xcomp mode on deep stack
+        assert stackDepth <= 1000;
         assert markAt <= stackDepth : "markAt(" + markAt + ") > stackDepth("
                 + stackDepth + ")";
         System.out.print("runTest(" + swOptions
@@ -297,15 +299,15 @@
             // Long stack, default maxDepth
             StackWalkTest swt;
             swt = new StackWalkTest();
-            swt.runTest(StackWalkTest.class, "main", 2000, 10);
+            swt.runTest(StackWalkTest.class, "main", 1000, 10);
 
             // Long stack, matching maxDepth
             swt = new StackWalkTest(2000);
-            swt.runTest(StackWalkTest.class, "main", 2000, 10);
+            swt.runTest(StackWalkTest.class, "main", 1000, 10);
 
             // Long stack, maximum maxDepth
             swt = new StackWalkTest(Integer.MAX_VALUE);
-            swt.runTest(StackWalkTest.class, "main", 2000, 10);
+            swt.runTest(StackWalkTest.class, "main", 1000, 10);
 
             //
             // Single batch
@@ -349,7 +351,7 @@
             swt.runTest(StackWalkTest.class, "main", 80, 40);
 
             swt = new StackWalkTest(EnumSet.of(RETAIN_CLASS_REFERENCE), 50);
-            swt.runTest(StackWalkTest.class, "main", 2000, 1048);
+            swt.runTest(StackWalkTest.class, "main", 1000, 524);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Thread/ITLConstructor.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Basic test for Thread(ThreadGroup,Runnable,String,long,boolean)
+ */
+
+public class ITLConstructor {
+    static InheritableThreadLocal<Integer> n = new InheritableThreadLocal<>() {
+        protected Integer initialValue() {
+            return 0;
+        }
+
+        protected Integer childValue(Integer parentValue) {
+            return parentValue + 1;
+        }
+    };
+
+    static final int CHILD_THREAD_COUNT = 10;
+
+    public static void main(String args[]) throws Exception {
+        test(true);
+        test(false);
+    }
+
+    static void test(boolean inherit) throws Exception {
+        // concurrent access to separate indexes is ok
+        int[] x = new int[CHILD_THREAD_COUNT];
+        Thread child = new Thread(Thread.currentThread().getThreadGroup(),
+                                  new AnotherRunnable(0, x, inherit),
+                                  "ITLConstructor-thread-"+(0),
+                                   0,
+                                   inherit);
+        child.start();
+        child.join(); // waits for *all* threads to complete
+
+        // Check results
+        for(int i=0; i<CHILD_THREAD_COUNT; i++) {
+            int expectedValue = 1;
+            if (inherit)
+                expectedValue = i+1;
+
+            if (x[i] != expectedValue)
+                throw (new Exception("Got x[" + i + "] = " + x[i]
+                                     + ", expected: " + expectedValue));
+        }
+    }
+
+    static class AnotherRunnable implements Runnable {
+        final int threadId;
+        final int[] x;
+        final boolean inherit;
+        AnotherRunnable(int threadId, int[] x, boolean inherit) {
+            this.threadId = threadId;
+            this.x = x;
+            this.inherit = inherit;
+        }
+
+        public void run() {
+            int itlValue = n.get();
+
+            if (threadId < CHILD_THREAD_COUNT-1) {
+                Thread child = new Thread(Thread.currentThread().getThreadGroup(),
+                                          new AnotherRunnable(threadId+1, x, inherit),
+                                          "ITLConstructor-thread-" + (threadId+1),
+                                          0,
+                                          inherit);
+                child.start();
+                try {
+                    child.join();
+                } catch(InterruptedException e) {
+                    throw(new RuntimeException("Interrupted", e));
+                }
+            }
+
+            x[threadId] = itlValue+1;
+        }
+    }
+}
--- a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java	Tue Dec 22 13:41:12 2015 -0800
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8004698 8007073 8022343 8054304 8058595
+ * @bug 8004698 8007073 8022343 8054304 8057804 8058595
  * @summary Unit test for type annotations
  */
 
@@ -358,6 +358,31 @@
         check(annos.length == 2);
         check(((TypeAnno)annos[0]).value().equals("I1"));
         check(args[0].getAnnotation(TypeAnno2.class).value().equals("I2"));
+
+        // check type args
+        Field f = TestParameterizedType.class.getDeclaredField("theField");
+        AnnotatedParameterizedType fType = (AnnotatedParameterizedType)f.getAnnotatedType();
+        args = fType.getAnnotatedActualTypeArguments();
+        check(args.length == 1);
+        annos = args[0].getAnnotations();
+        check(annos.length == 1);
+        check(((TypeAnno2)annos[0]).value().equals("Map Arg"));
+        check(args[0].getAnnotation(TypeAnno2.class).value().equals("Map Arg"));
+
+        // check outer type type args
+        fType = (AnnotatedParameterizedType)fType.getAnnotatedOwnerType();
+        args = fType.getAnnotatedActualTypeArguments();
+        check(args.length == 1);
+        annos = args[0].getAnnotations();
+        check(annos.length == 1);
+        check(((TypeAnno2)annos[0]).value().equals("String Arg"));
+        check(args[0].getAnnotation(TypeAnno2.class).value().equals("String Arg"));
+
+        // check outer type normal type annotations
+        annos = fType.getAnnotations();
+        check(annos.length == 1);
+        check(((TypeAnno)annos[0]).value().equals("FieldOuter"));
+        check(fType.getAnnotation(TypeAnno.class).value().equals("FieldOuter"));
     }
 
     private static void testWildcardType() throws Exception {
@@ -563,9 +588,12 @@
 abstract class TestParameterizedType implements @TypeAnno("M") Map<@TypeAnno("S")String, @TypeAnno("I") @TypeAnno2("I2")Integer> {
     public ParameterizedOuter<String>.ParameterizedInner<Integer> foo() {return null;}
     public @TypeAnno("O") ParameterizedOuter<@TypeAnno("S1") @TypeAnno2("S2") String>.
-               @TypeAnno("I") ParameterizedInner<@TypeAnno("I1") @TypeAnno2("I2")Integer> foo2() {
+            @TypeAnno("I") ParameterizedInner<@TypeAnno("I1") @TypeAnno2("I2")Integer> foo2() {
         return null;
     }
+
+    public @TypeAnno("FieldOuter") ParameterizedOuter<@TypeAnno2("String Arg") String>.
+            @TypeAnno("FieldInner")ParameterizedInner<@TypeAnno2("Map Arg")Map> theField;
 }
 
 class ParameterizedOuter <T> {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedOwnerType.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058595
+ * @summary Test that AnnotatedType.getAnnotatedOwnerType() works as expected
+ *
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.Asserts
+ * @run main GetAnnotatedOwnerType
+ */
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import jdk.testlibrary.Asserts;
+
+public class GetAnnotatedOwnerType<Dummy> {
+    public @TA("generic") GetAnnotatedOwnerType<String> . @TB("generic") Nested<Integer> genericField;
+    public @TA("raw") GetAnnotatedOwnerType . @TB("raw") Nested rawField;
+    public @TA("non-generic") GetAnnotatedOwnerTypeAuxilliary . @TB("non-generic") Inner nonGeneric;
+    public @TA("non-generic") GetAnnotatedOwnerTypeAuxilliary . @TB("generic") InnerGeneric<String> innerGeneric;
+    public @TA("non-generic") GetAnnotatedOwnerTypeAuxilliary . @TB("raw") InnerGeneric innerRaw;
+    public Object anonymous = new Object() {};
+    public @TA("array") Dummy[] dummy;
+    public @TA("wildcard") GetAnnotatedOwnerType<?> wildcard;
+    public @TA("typevariable") Dummy tv;
+    public @TA("bad") GetAnnotatedOwnerType<@TA("good") GetAnnotatedOwnerType<String> . @TB("tb") Nested<Integer> >  typeArgument;
+    public GetAnnotatedOwnerType< GetAnnotatedOwnerType<String> .
+            B .
+            C<Class<?>, ? extends @TA("complicated") Exception> .
+            D<Number> > [] complicated;
+
+    public static void main(String[] args) throws Exception {
+        testGeneric();
+        testRaw();
+        testNonGeneric();
+        testInnerGeneric();
+        testInnerRaw();
+
+        testLocalClass();
+        testAnonymousClass();
+
+        testArray();
+        testWildcard();
+        testTypeParameter();
+
+        testTypeArgument();
+        testComplicated();
+    }
+
+    public static void testGeneric() throws Exception {
+        Field f = GetAnnotatedOwnerType.class.getField("genericField");
+
+        // make sure inner is correctly annotated
+        AnnotatedType inner = f.getAnnotatedType();
+        Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "generic");
+        Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + inner.getAnnotations().length);
+
+        // make sure owner is correctly annotated, on the correct type
+        AnnotatedType outer = inner.getAnnotatedOwnerType();
+        Asserts.assertEquals(outer.getType(), ((ParameterizedType) f.getGenericType()).getOwnerType());
+        Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "generic");
+        Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + outer.getAnnotations().length);
+    }
+
+    public static void testRaw() throws Exception {
+        Field f = GetAnnotatedOwnerType.class.getField("rawField");
+
+        // make sure inner is correctly annotated
+        AnnotatedType inner = f.getAnnotatedType();
+        Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "raw");
+        Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + inner.getAnnotations().length);
+
+        // make sure owner is correctly annotated, on the correct type
+        AnnotatedType outer = inner.getAnnotatedOwnerType();
+        Asserts.assertEquals(outer.getType(), ((Class<?>)f.getGenericType()).getEnclosingClass());
+        Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "raw");
+        Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + outer.getAnnotations().length);
+    }
+
+    public static void testNonGeneric() throws Exception {
+        Field f = GetAnnotatedOwnerType.class.getField("nonGeneric");
+
+        // make sure inner is correctly annotated
+        AnnotatedType inner = f.getAnnotatedType();
+        Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "non-generic");
+        Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + inner.getAnnotations().length);
+
+        // make sure owner is correctly annotated, on the correct type
+        AnnotatedType outer = inner.getAnnotatedOwnerType();
+        Asserts.assertEquals(outer.getType(), ((Class<?>)f.getGenericType()).getEnclosingClass());
+        Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "non-generic");
+        Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + outer.getAnnotations().length);
+    }
+
+    public static void testInnerGeneric() throws Exception {
+        Field f = GetAnnotatedOwnerType.class.getField("innerGeneric");
+
+        // make sure inner is correctly annotated
+        AnnotatedType inner = f.getAnnotatedType();
+        Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "generic");
+        Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + inner.getAnnotations().length);
+
+        // make sure owner is correctly annotated, on the correct type
+        AnnotatedType outer = inner.getAnnotatedOwnerType();
+        Asserts.assertEquals(outer.getType(), ((ParameterizedType) f.getGenericType()).getOwnerType());
+        Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "non-generic");
+        Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + outer.getAnnotations().length);
+    }
+
+    public static void testInnerRaw() throws Exception {
+        Field f = GetAnnotatedOwnerType.class.getField("innerRaw");
+
+        // make sure inner is correctly annotated
+        AnnotatedType inner = f.getAnnotatedType();
+        Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "raw");
+        Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + inner.getAnnotations().length);
+
+        // make sure owner is correctly annotated, on the correct type
+        AnnotatedType outer = inner.getAnnotatedOwnerType();
+        Asserts.assertEquals(outer.getType(), ((Class<?>)f.getGenericType()).getEnclosingClass());
+        Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "non-generic");
+        Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + outer.getAnnotations().length);
+    }
+
+    public static void testLocalClass() throws Exception {
+        class ALocalClass {}
+        class OneMore {
+            public @TA("null") ALocalClass c;
+        }
+        testNegative(OneMore.class.getField("c").getAnnotatedType(), "Local class should return null");
+    }
+
+    public static void testAnonymousClass() throws Exception {
+        testNegative(GetAnnotatedOwnerType.class.getField("anonymous").getAnnotatedType(),
+                "Anonymous class should return null");
+    }
+
+    public static void testArray() throws Exception {
+        AnnotatedType t = GetAnnotatedOwnerType.class.getField("dummy").getAnnotatedType();
+        Asserts.assertTrue((t instanceof AnnotatedArrayType),
+                "Was expecting an AnnotatedArrayType " + t);
+        testNegative(t, "" + t + " should not have an annotated owner type");
+    }
+
+    public static void testWildcard() throws Exception {
+        AnnotatedType tt = GetAnnotatedOwnerType.class.getField("wildcard").getAnnotatedType();
+        AnnotatedType t = ((AnnotatedParameterizedType)tt).getAnnotatedActualTypeArguments()[0];
+        Asserts.assertTrue((t instanceof AnnotatedWildcardType),
+                "Was expecting an AnnotatedWildcardType " + t);
+        testNegative(t, "" + t + " should not have an annotated owner type");
+    }
+
+    public static void testTypeParameter() throws Exception {
+        AnnotatedType t = GetAnnotatedOwnerType.class.getField("tv").getAnnotatedType();
+        Asserts.assertTrue((t instanceof AnnotatedTypeVariable),
+                "Was expecting an AnnotatedTypeVariable " + t);
+        testNegative(t, "" + t + " should not have an annotated owner type");
+    }
+
+    public static void testTypeArgument() throws Exception {
+        AnnotatedType tt = GetAnnotatedOwnerType.class.getField("typeArgument").getAnnotatedType();
+        Asserts.assertEquals(tt.getAnnotation(TA.class).value(), "bad");
+        Asserts.assertTrue(tt.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + tt.getAnnotations().length);
+
+        // make sure inner is correctly annotated
+        AnnotatedType inner = ((AnnotatedParameterizedType)tt).getAnnotatedActualTypeArguments()[0];
+        Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "tb");
+        Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + inner.getAnnotations().length);
+
+        // make sure owner is correctly annotated
+        AnnotatedType outer = inner.getAnnotatedOwnerType();
+        Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "good");
+        Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + outer.getAnnotations().length);
+    }
+
+    public static void testComplicated() throws Exception {
+        Field f = GetAnnotatedOwnerType.class.getField("complicated");
+
+        // Outermost level
+        AnnotatedType t = f.getAnnotatedType();
+        Asserts.assertTrue((t instanceof AnnotatedArrayType),
+                "Was expecting an AnnotatedArrayType " + t);
+        testNegative(t, "" + t + " should not have an annotated owner type");
+        Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: "
+                + t.getAnnotations().length);
+
+        // Component type
+        t = ((AnnotatedArrayType)t).getAnnotatedGenericComponentType();
+        testNegative(t, "" + t + " should not have an annotated owner type");
+        Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: "
+                + t.getAnnotations().length);
+
+        // Type arg GetAnnotatedOwnerType<String>...D<Number>
+        t = ((AnnotatedParameterizedType)t).getAnnotatedActualTypeArguments()[0];
+        Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: "
+                + t.getAnnotations().length);
+
+        // C<Class<?>, ? extends ...>
+        t = t.getAnnotatedOwnerType();
+        Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: "
+                + t.getAnnotations().length);
+
+        // ? extends
+        t = ((AnnotatedParameterizedType)t).getAnnotatedActualTypeArguments()[1];
+        testNegative(t, "" + t + " should not have an annotated owner type");
+        Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: "
+                + t.getAnnotations().length);
+
+        // @TA("complicated") Exception
+        t = ((AnnotatedWildcardType)t).getAnnotatedUpperBounds()[0];
+        testNegative(t, "" + t + " should not have an annotated owner type");
+        Asserts.assertEquals(t.getAnnotation(TA.class).value(), "complicated");
+        Asserts.assertTrue(t.getAnnotations().length == 1, "expecting one (1) annotation, got: "
+                + t.getAnnotations().length);
+    }
+
+    private static void testNegative(AnnotatedType t, String msg) {
+        Asserts.assertNull(t.getAnnotatedOwnerType(), msg);
+    }
+
+    public class Nested<AlsoDummy> {}
+    public class B {
+        public class C<R, S> {
+            public class D<T> {
+            }
+        }
+    }
+
+    @Target(ElementType.TYPE_USE)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface TA {
+        String value();
+    }
+
+    @Target(ElementType.TYPE_USE)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface TB {
+        String value();
+    }
+}
+
+class GetAnnotatedOwnerTypeAuxilliary {
+    class Inner {}
+
+    class InnerGeneric<Dummy> {}
+}
--- a/jdk/test/java/lang/reflect/Proxy/CharType.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/lang/reflect/Proxy/CharType.java	Tue Dec 22 13:41:12 2015 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 4346224
- * @summary Test against a typo in sun.misc.ProxyGenerator:
+ * @summary Test against a typo in ProxyGenerator:
  *          "java/lang/Character" should be used instead of
  *          "java/lang/Char".
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Format/DateFormat/Bug8139572.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8139572
+ * @summary SimpleDateFormat parse month stand-alone format bug
+ * @compile -encoding utf-8 Bug8139572.java
+ * @run main Bug8139572
+ */
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+public class Bug8139572 {
+
+    private static final Locale RUSSIAN = new Locale("ru");
+    private static final Date SEPT12 = new GregorianCalendar(2015, Calendar.SEPTEMBER, 12).getTime();
+
+    private static final String[] PATTERNS = {
+        "L",
+        "dd L",
+        "dd L yy",
+        "dd L yyyy",
+        "LL",
+        "dd LL",
+        "dd LL yy",
+        "dd LL yyyy",
+        "LLL",
+        "dd LLL",
+        "dd LLL yy",
+        "dd LLL yyyy",
+        "LLLL",
+        "dd LLLL",
+        "dd LLLL yy",
+        "dd LLLL yyyy"
+    };
+
+    private static final String[] APPLIED = {
+        "9",
+        "12 09",
+        "12 09 15",
+        "12 09 2015",
+        "09",
+        "12 09",
+        "12 09 15",
+        "12 09 2015",
+        "сентября",
+        "12 сентября",
+        "12 сентября 15",
+        "12 сентября 2015",
+        "сентября",
+        "12 сентября",
+        "12 сентября 15",
+        "12 сентября 2015"
+    };
+
+    private static final String[] EXPECTED = {
+        "9",
+        "12 9",
+        "12 9 15",
+        "12 9 2015",
+        "09",
+        "12 09",
+        "12 09 15",
+        "12 09 2015",
+        "сент.",
+        "12 сент.",
+        "12 сент. 15",
+        "12 сент. 2015",
+        "сентябрь",
+        "12 сентябрь",
+        "12 сентябрь 15",
+        "12 сентябрь 2015"
+    };
+
+    public static void main(String[] args) throws ParseException {
+
+        for (int i = 0; i < PATTERNS.length; i++) {
+            SimpleDateFormat fmt = new SimpleDateFormat(PATTERNS[i], RUSSIAN);
+            Date standAloneDate = fmt.parse(APPLIED[i]);
+            String str = fmt.format(standAloneDate);
+            if (!EXPECTED[i].equals(str)) {
+                throw new RuntimeException("bad result: got '" + str + "', expected '" + EXPECTED[i] + "'");
+            }
+        }
+
+        SimpleDateFormat fmt = new SimpleDateFormat("", RUSSIAN);
+        for (int j = 0; j < PATTERNS.length; j++) {
+            fmt.applyPattern(PATTERNS[j]);
+            String str = fmt.format(SEPT12);
+            if (!EXPECTED[j].equals(str)) {
+                throw new RuntimeException("bad result: got '" + str + "', expected '" + EXPECTED[j] + "'");
+            }
+        }
+    }
+}
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java	Tue Dec 22 13:41:12 2015 -0800
@@ -2393,6 +2393,65 @@
     }
 
     //-----------------------------------------------------------------------
+    // dividedbyDur()
+    //-----------------------------------------------------------------------
+
+    @DataProvider(name="dividedByDur_provider")
+    Object[][] provider_dividedByDur() {
+        return new Object[][] {
+            {Duration.ofSeconds(0, 0), Duration.ofSeconds(1, 0), 0},
+            {Duration.ofSeconds(1, 0), Duration.ofSeconds(1, 0), 1},
+            {Duration.ofSeconds(6, 0), Duration.ofSeconds(3, 0), 2},
+            {Duration.ofSeconds(3, 0), Duration.ofSeconds(6, 0), 0},
+            {Duration.ofSeconds(7, 0), Duration.ofSeconds(3, 0), 2},
+
+            {Duration.ofSeconds(0, 333_333_333), Duration.ofSeconds(0, 333_333_333), 1},
+            {Duration.ofSeconds(0, 666_666_666), Duration.ofSeconds(0, 333_333_333), 2},
+            {Duration.ofSeconds(0, 333_333_333), Duration.ofSeconds(0, 666_666_666), 0},
+            {Duration.ofSeconds(0, 777_777_777), Duration.ofSeconds(0, 333_333_333), 2},
+
+            {Duration.ofSeconds(-7, 0), Duration.ofSeconds(3, 0), -2},
+            {Duration.ofSeconds(0, 7), Duration.ofSeconds(0, -3), -2},
+            {Duration.ofSeconds(0, -777_777_777), Duration.ofSeconds(0, 333_333_333), -2},
+
+            {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), 29},
+            {Duration.ofSeconds(-432000L, 777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), -29},
+            {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), -29},
+            {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(14400L, -333_333_333L), -30},
+            {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(-14400L, 333_333_333L), -30},
+            {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(-14400L, -333_333_333L), -29},
+            {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(-14400L, -333_333_333L), 29},
+
+            {Duration.ofSeconds(Long.MAX_VALUE, 0), Duration.ofSeconds(1, 0), Long.MAX_VALUE},
+            {Duration.ofSeconds(Long.MAX_VALUE, 0), Duration.ofSeconds(Long.MAX_VALUE, 0), 1},
+        };
+    }
+
+    @Test(dataProvider="dividedByDur_provider")
+    public void test_dividedByDur(Duration dividend, Duration divisor, long expected) {
+        assertEquals(dividend.dividedBy(divisor), expected);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_dividedByDur_zero() {
+       Duration t = Duration.ofSeconds(1, 0);
+       t.dividedBy(Duration.ZERO);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_dividedByDur_null() {
+       Duration t = Duration.ofSeconds(1, 0);
+       t.dividedBy(null);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_dividedByDur_overflow() {
+       Duration dur1 = Duration.ofSeconds(Long.MAX_VALUE, 0);
+       Duration dur2 = Duration.ofNanos(1);
+       dur1.dividedBy(dur2);
+    }
+
+    //-----------------------------------------------------------------------
     // negated()
     //-----------------------------------------------------------------------
     @Test
--- a/jdk/test/java/util/Collections/AsLifoQueue.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/util/Collections/AsLifoQueue.java	Tue Dec 22 13:41:12 2015 -0800
@@ -70,6 +70,8 @@
             check(q.isEmpty());
             equal(q.size(), 0);
         } catch (Throwable t) { unexpected(t); }
+
+        THROWS(NullPointerException.class, () -> Collections.asLifoQueue(null));
     }
 
     //--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/regex/PatternStreamTest.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/util/regex/PatternStreamTest.java	Tue Dec 22 13:41:12 2015 -0800
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8016846 8024341 8071479
+ * @bug 8016846 8024341 8071479 8145006
  * @summary Unit tests stream and lambda-based methods on Pattern and Matcher
  * @library ../stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
@@ -42,6 +42,7 @@
 import java.util.regex.MatchResult;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
@@ -185,6 +186,20 @@
                 .exercise();
     }
 
+    @Test
+    public void testLateBinding() {
+        Pattern pattern = Pattern.compile(",");
+
+        StringBuilder sb = new StringBuilder("a,b,c,d,e");
+        Stream<String> stream = pattern.splitAsStream(sb);
+        sb.setLength(3);
+        assertEquals(Arrays.asList("a", "b"), stream.collect(Collectors.toList()));
+
+        stream = pattern.splitAsStream(sb);
+        sb.append(",f,g");
+        assertEquals(Arrays.asList("a", "b", "f", "g"), stream.collect(Collectors.toList()));
+    }
+
     public void testFailfastMatchResults() {
         Pattern p = Pattern.compile("X");
         Matcher m = p.matcher("XX");
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java	Tue Dec 22 13:41:12 2015 -0800
@@ -56,6 +56,7 @@
 
 import static java.util.stream.Collectors.collectingAndThen;
 import static java.util.stream.Collectors.flatMapping;
+import static java.util.stream.Collectors.filtering;
 import static java.util.stream.Collectors.groupingBy;
 import static java.util.stream.Collectors.groupingByConcurrent;
 import static java.util.stream.Collectors.mapping;
@@ -72,7 +73,7 @@
 
 /*
  * @test
- * @bug 8071600
+ * @bug 8071600 8144675
  * @summary Test for collectors.
  */
 public class CollectorsTest extends OpTestCase {
@@ -118,6 +119,23 @@
         }
     }
 
+    static class FilteringAssertion<T, R> extends CollectorAssertion<T, R> {
+        private final Predicate<T> filter;
+        private final CollectorAssertion<T, R> downstream;
+
+        public FilteringAssertion(Predicate<T> filter, CollectorAssertion<T, R> downstream) {
+            this.filter = filter;
+            this.downstream = downstream;
+        }
+
+        @Override
+        void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
+            downstream.assertValue(value,
+                                   () -> source.get().filter(filter),
+                                   ordered);
+        }
+    }
+
     static class GroupingByAssertion<T, K, V, M extends Map<K, ? extends V>> extends CollectorAssertion<T, M> {
         private final Class<? extends Map> clazz;
         private final Function<T, K> classifier;
@@ -551,6 +569,36 @@
     }
 
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testGroupingByWithFiltering(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+        Predicate<Integer> filteringByMod2 = i -> i % 2 == 0;
+        Predicate<Integer> filteringByUnder100 = i -> i % 2 < 100;
+        Predicate<Integer> filteringByTrue = i -> true;
+        Predicate<Integer> filteringByFalse = i -> false;
+
+        exerciseMapCollection(data,
+                              groupingBy(classifier, filtering(filteringByMod2, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FilteringAssertion<>(filteringByMod2,
+                                                                                   new ToListAssertion<>())));
+        exerciseMapCollection(data,
+                              groupingBy(classifier, filtering(filteringByUnder100, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FilteringAssertion<>(filteringByUnder100,
+                                                                                   new ToListAssertion<>())));
+        exerciseMapCollection(data,
+                              groupingBy(classifier, filtering(filteringByTrue, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FilteringAssertion<>(filteringByTrue,
+                                                                                   new ToListAssertion<>())));
+        exerciseMapCollection(data,
+                              groupingBy(classifier, filtering(filteringByFalse, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FilteringAssertion<>(filteringByFalse,
+                                                                                   new ToListAssertion<>())));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testTwoLevelGroupingBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
         Function<Integer, Integer> classifier = i -> i % 6;
         Function<Integer, Integer> classifier2 = i -> i % 23;
--- a/jdk/test/java/util/zip/TestZipError.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/util/zip/TestZipError.java	Tue Dec 22 13:41:12 2015 -0800
@@ -84,9 +84,10 @@
         try {
             while (entries.hasMoreElements()) {
                 ze = entries.nextElement();
+                zf.getInputStream(ze).readAllBytes();
             }
             fail("Did not get expected exception");
-        } catch (ZipError e) {
+        } catch (ZipException e) {
             pass();
         } catch (InternalError e) {
             fail("Caught InternalError instead of expected ZipError");
--- a/jdk/test/java/util/zip/ZipFile/ReadZip.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/java/util/zip/ZipFile/ReadZip.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,6 +30,7 @@
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.nio.file.NoSuchFileException;
 import java.nio.file.StandardCopyOption;
 import java.nio.file.StandardOpenOption;
 import java.util.zip.*;
@@ -110,6 +111,6 @@
                                      "input"
                                       + String.valueOf(new java.util.Random().nextInt())
                                       + ".zip")));
-        } catch (FileNotFoundException fnfe) {}
+        } catch (NoSuchFileException nsfe) {}
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/zip/ZipFile/TestZipFile.java	Tue Dec 22 13:41:12 2015 -0800
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8142508
+ * @summary Tests various ZipFile apis
+ * @run main/manual TestZipFile
+ */
+
+import java.io.*;
+import java.lang.reflect.Method;
+import java.nio.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.zip.*;
+
+public class TestZipFile {
+
+    private static Random r = new Random();
+    private static int    N = 50;
+    private static int    NN = 10;
+    private static int    ENUM = 10000;
+    private static int    ESZ = 10000;
+    private static ExecutorService executor = Executors.newFixedThreadPool(20);
+    private static Set<Path> paths = new HashSet<>();
+
+    static void realMain (String[] args) throws Throwable {
+
+        try {
+            for (int i = 0; i < N; i++) {
+                test(r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+                test(r.nextInt(ENUM), r.nextInt(ESZ), true, true);
+            }
+
+            for (int i = 0; i < NN; i++) {
+                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), false, true);
+                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), true, true);
+                testCachedDelete();
+                testCachedOverwrite();
+                //test(r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+            }
+
+            test(70000, 1000, false, true);   // > 65536 entry number;
+            testDelete();                     // OPEN_DELETE
+
+            executor.shutdown();
+            executor.awaitTermination(10, TimeUnit.MINUTES);
+        } finally {
+            for (Path path : paths) {
+                Files.deleteIfExists(path);
+            }
+        }
+    }
+
+    static void test(int numEntry, int szMax, boolean addPrefix, boolean cleanOld) {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip = new Zip(name, numEntry, szMax, addPrefix, cleanOld);
+        for (int i = 0; i < NN; i++) {
+            executor.submit(() -> doTest(zip));
+        }
+     }
+
+    // test scenario:
+    // (1) open the ZipFile(zip) with OPEN_READ | OPEN_DELETE
+    // (2) test the ZipFile works correctly
+    // (3) check the zip is deleted after ZipFile gets closed
+    static void testDelete() throws Throwable {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+        try (ZipFile zf = new ZipFile(new File(zip.name),
+                                      ZipFile.OPEN_READ | ZipFile.OPEN_DELETE ))
+        {
+            doTest0(zip, zf);
+        }
+        Path p = Paths.get(name);
+        if (Files.exists(p)) {
+            fail("Failed to delete " + name + " with OPEN_DELETE");
+        }
+    }
+
+    // test scenario:
+    // (1) keep a ZipFile(zip1) alive (in ZipFile's cache), dont close it
+    // (2) delete zip1 and create zip2 with the same name the zip1 with zip2
+    // (3) zip1 tests should fail, but no crash
+    // (4) zip2 tasks should all get zip2, then pass normal testing.
+    static void testCachedDelete() throws Throwable {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+
+        try (ZipFile zf = new ZipFile(zip1.name)) {
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> verifyNoCrash(zip1));
+            }
+            // delete the "zip1"  and create a new one to test
+            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+            /*
+                System.out.println("========================================");
+                System.out.printf("    zip1=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
+                    zip1.name, zip1.lastModified, zip1.entries.size(),
+                    zip1.attrs.fileKey(), zip1.attrs.size(), zip1.attrs.lastModifiedTime().toMillis());
+                System.out.printf("    zip2=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
+                    zip2.name, zip2.lastModified, zip2.entries.size(),
+                    zip2.attrs.fileKey(), zip2.attrs.size(), zip2.attrs.lastModifiedTime().toMillis());
+            */
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> doTest(zip2));
+            }
+        }
+    }
+
+   // overwrite the "zip1"  and create a new one to test. So the two zip files
+   // have the same fileKey, but probably different lastModified()
+    static void testCachedOverwrite() throws Throwable {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+        try (ZipFile zf = new ZipFile(zip1.name)) {
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> verifyNoCrash(zip1));
+            }
+            // overwrite the "zip1"  with new contents
+            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, false);
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> doTest(zip2));
+            }
+        }
+    }
+
+    // just check the entries and contents. since the file has been either overwritten
+    // or deleted/rewritten, we only care if it crahes or not.
+    static void verifyNoCrash(Zip zip) throws RuntimeException {
+        try (ZipFile zf = new ZipFile(zip.name)) {
+            List<ZipEntry> zlist = new ArrayList(zip.entries.keySet());
+            String[] elist = zf.stream().map( e -> e.getName()).toArray(String[]::new);
+            if (!Arrays.equals(elist,
+                               zlist.stream().map( e -> e.getName()).toArray(String[]::new)))
+            {
+                //System.out.printf("++++++ LIST NG [%s] entries.len=%d, expected=%d+++++++%n",
+                //                  zf.getName(), elist.length, zlist.size());
+                return;
+            }
+            for (ZipEntry ze : zlist) {
+                byte[] zdata = zip.entries.get(ze);
+                ZipEntry e = zf.getEntry(ze.getName());
+                if (e != null) {
+                    checkEqual(e, ze);
+                    if (!e.isDirectory()) {
+                        // check with readAllBytes
+                        try (InputStream is = zf.getInputStream(e)) {
+                            if (!Arrays.equals(zdata, is.readAllBytes())) {
+                                //System.out.printf("++++++ BYTES NG  [%s]/[%s] ++++++++%n",
+                                //                  zf.getName(), ze.getName());
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            // t.printStackTrace();
+            // fail(t.toString());
+        }
+    }
+
+    static void checkEqual(ZipEntry x, ZipEntry y) {
+        if (x.getName().equals(y.getName()) &&
+            x.isDirectory() == y.isDirectory() &&
+            x.getMethod() == y.getMethod() &&
+            (x.getTime() / 2000) == y.getTime() / 2000 &&
+            x.getSize() == y.getSize() &&
+            x.getCompressedSize() == y.getCompressedSize() &&
+            x.getCrc() == y.getCrc() &&
+            x.getComment().equals(y.getComment())
+        ) {
+            pass();
+        } else {
+            fail(x + " not equal to " + y);
+            System.out.printf("      %s       %s%n", x.getName(), y.getName());
+            System.out.printf("      %d       %d%n", x.getMethod(), y.getMethod());
+            System.out.printf("      %d       %d%n", x.getTime(), y.getTime());
+            System.out.printf("      %d       %d%n", x.getSize(), y.getSize());
+            System.out.printf("      %d       %d%n", x.getCompressedSize(), y.getCompressedSize());
+            System.out.printf("      %d       %d%n", x.getCrc(), y.getCrc());
+            System.out.println("-----------------");
+        }
+    }
+
+    static void doTest(Zip zip) throws RuntimeException {
+        //Thread me = Thread.currentThread();
+        try (ZipFile zf = new ZipFile(zip.name)) {
+            doTest0(zip, zf);
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    static void doTest0(Zip zip, ZipFile zf) throws Throwable {
+        List<ZipEntry> list = new ArrayList(zip.entries.keySet());
+        // (1) check entry list, in expected order
+        if (!check(Arrays.equals(
+                list.stream().map( e -> e.getName()).toArray(String[]::new),
+                zf.stream().map( e -> e.getName()).toArray(String[]::new)))) {
+            return;
+        }
+        // (2) shuffle, and check each entry and its bytes
+        Collections.shuffle(list);
+        for (ZipEntry ze : list) {
+            byte[] data = zip.entries.get(ze);
+            ZipEntry e = zf.getEntry(ze.getName());
+            checkEqual(e, ze);
+            if (!e.isDirectory()) {
+                // check with readAllBytes
+                try (InputStream is = zf.getInputStream(e)) {
+                    check(Arrays.equals(data, is.readAllBytes()));
+                }
+                // check with smaller sized buf
+                try (InputStream is = zf.getInputStream(e)) {
+                    byte[] buf = new byte[(int)e.getSize()];
+                    int sz = r.nextInt((int)e.getSize()/4 + 1) + 1;
+                    int off = 0;
+                    int n;
+                    while ((n = is.read(buf, off, buf.length - off)) > 0) {
+                        off += n;
+                    }
+                    check(is.read() == -1);
+                    check(Arrays.equals(data, buf));
+                }
+            }
+        }
+        // (3) check getMetaInfEntryNames
+        String[] metas = list.stream()
+                             .map( e -> e.getName())
+                             .filter( s -> s.startsWith("META-INF/"))
+                             .sorted()
+                             .toArray(String[]::new);
+        if (metas.length > 0) {
+            // meta-inf entries
+            Method getMetas = ZipFile.class.getDeclaredMethod("getMetaInfEntryNames");
+            getMetas.setAccessible(true);
+            String[] names = (String[])getMetas.invoke(zf);
+            if (names == null) {
+                fail("Failed to get metanames from " + zf);
+            } else {
+                Arrays.sort(names);
+                check(Arrays.equals(names, metas));
+            }
+        }
+    }
+
+    private static class Zip {
+        String name;
+        Map<ZipEntry, byte[]> entries;
+        BasicFileAttributes attrs;
+        long lastModified;
+
+        Zip(String name, int num, int szMax, boolean prefix, boolean clean) {
+            this.name = name;
+            entries = new LinkedHashMap<>(num);
+            try {
+                Path p = Paths.get(name);
+                if (clean) {
+                    Files.deleteIfExists(p);
+                }
+                paths.add(p);
+            } catch (Exception x) {
+                throw (RuntimeException)x;
+            }
+
+            try (FileOutputStream fos = new FileOutputStream(name);
+                 BufferedOutputStream bos = new BufferedOutputStream(fos);
+                 ZipOutputStream zos = new ZipOutputStream(bos))
+            {
+                if (prefix) {
+                    byte[] bytes = new byte[r.nextInt(1000)];
+                    r.nextBytes(bytes);
+                    bos.write(bytes);
+                }
+                CRC32 crc = new CRC32();
+                for (int i = 0; i < num; i++) {
+                    String ename = "entry-" + i + "-name-" + r.nextLong();
+                    ZipEntry ze = new ZipEntry(ename);
+                    int method = r.nextBoolean() ? ZipEntry.STORED : ZipEntry.DEFLATED;
+                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
+                }
+                // add some manifest entries
+                for (int i = 0; i < r.nextInt(20); i++) {
+                    String meta = "META-INF/" + "entry-" + i + "-metainf-" + r.nextLong();
+                    ZipEntry ze = new ZipEntry(meta);
+                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
+                }
+            } catch (Exception x) {
+                throw (RuntimeException)x;
+            }
+            try {
+                this.attrs = Files.readAttributes(Paths.get(name), BasicFileAttributes.class);
+                this.lastModified = new File(name).lastModified();
+            } catch (Exception x) {
+                throw (RuntimeException)x;
+            }
+        }
+
+        private void writeEntry(ZipOutputStream zos, CRC32 crc,
+                                ZipEntry ze, int method, int szMax)
+            throws IOException
+        {
+            ze.setMethod(method);
+            byte[] data = new byte[r.nextInt(szMax + 1)];
+            r.nextBytes(data);
+            if (method == ZipEntry.STORED) {  // must set size/csize/crc
+                ze.setSize(data.length);
+                ze.setCompressedSize(data.length);
+                crc.reset();
+                crc.update(data);
+                ze.setCrc(crc.getValue());
+            }
+            ze.setTime(System.currentTimeMillis());
+            ze.setComment(ze.getName());
+            zos.putNextEntry(ze);
+            zos.write(data);
+            zos.closeEntry();
+            entries.put(ze, data);
+        }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void pass(String msg) {System.out.println(msg); passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void unexpected(Throwable t, String msg) {
+        System.out.println(msg); failed++; t.printStackTrace();}
+    static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.println("\nPassed = " + passed + " failed = " + failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- a/jdk/test/javax/net/ssl/DTLS/DTLSOverDatagram.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/javax/net/ssl/DTLS/DTLSOverDatagram.java	Tue Dec 22 13:41:12 2015 -0800
@@ -28,6 +28,7 @@
  * @test
  * @bug 8043758
  * @summary Datagram Transport Layer Security (DTLS)
+ * @modules java.base/sun.security.util
  * @run main/othervm DTLSOverDatagram
  */
 
@@ -40,7 +41,7 @@
 import javax.net.ssl.*;
 import java.util.concurrent.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /**
  * An example to show the way to use SSLEngine in datagram connections.
--- a/jdk/test/javax/net/ssl/templates/SSLExplorer.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/javax/net/ssl/templates/SSLExplorer.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,8 +29,6 @@
 import javax.net.ssl.*;
 import java.util.*;
 
-import sun.misc.HexDumpEncoder;
-
 /**
  * Instances of this class acts as an explorer of the network data of an
  * SSL/TLS connection.
--- a/jdk/test/javax/print/PrintSEUmlauts/PrintSEUmlauts.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/javax/print/PrintSEUmlauts/PrintSEUmlauts.java	Tue Dec 22 13:41:12 2015 -0800
@@ -107,14 +107,14 @@
                 System.err.println("printing content");
                 System.err.println(content);
             }
-            throw new RuntimeException("Expected <e4> to represent 'ä' but not found!");
+            throw new RuntimeException("Expected <e4> to represent '\u00e4' but not found!");
         }
         System.err.println("SUCCESS");
     }
 
     public int print(Graphics g, PageFormat pf, int pg) {
        if (pg > 0) return NO_SUCH_PAGE;
-       g.drawString("ä", 100, 100);
+       g.drawString("\u00e4", 100, 100);
        return PAGE_EXISTS;
    }
 }
--- a/jdk/test/javax/security/auth/Subject/Subject.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/javax/security/auth/Subject/Subject.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,7 +29,6 @@
  */
 package jjjjj.security.auth;
 
-import sun.misc.HexDumpEncoder;
 import javax.management.remote.JMXPrincipal;
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.x500.X500Principal;
@@ -107,7 +106,6 @@
 
     public static byte[] enc(Object obj) {
         try {
-            HexDumpEncoder hex = new HexDumpEncoder();
             ByteArrayOutputStream bout;
             bout = new ByteArrayOutputStream();
             new ObjectOutputStream(bout).writeObject(obj);
--- a/jdk/test/javax/xml/crypto/dsig/SecurityManager/XMLDSigWithSecMgr.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/javax/xml/crypto/dsig/SecurityManager/XMLDSigWithSecMgr.java	Tue Dec 22 13:41:12 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -33,8 +33,6 @@
 import java.net.*;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
-import java.security.Policy;
-import java.security.URIParameter;
 import java.util.ArrayList;
 import java.util.Collections;
 import javax.xml.crypto.dsig.*;
@@ -115,10 +113,8 @@
 
         // the policy only grants this test SocketPermission to accept, resolve
         // and connect to localhost so that it can dereference 2nd reference
-        URI policyURI =
-            new File(System.getProperty("test.src", "."), "policy").toURI();
-        Policy.setPolicy
-            (Policy.getInstance("JavaPolicy", new URIParameter(policyURI)));
+        System.setProperty("java.security.policy",
+                System.getProperty("test.src", ".") + File.separator + "policy");
         System.setSecurityManager(new SecurityManager());
 
         try {
--- a/jdk/test/sun/misc/Encode/DecodeBuffer.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 4159554
- * @summary Problem with UUDecoder
- * @modules java.base/sun.misc
- */
-
-import sun.misc.*;
-import java.io.*;
-
-public class DecodeBuffer {
-
-    public static void main(String[] args) throws Exception {
-        String encoded;
-        // text to encode and decode
-        String originalText = "Hi There, please encode and decode me";
-        UUDecoder uuD = new UUDecoder();
-
-        encoded = "begin 644 encoder.buf\r\n" +
-          "E2&D@5&AE<F4L('!L96%S92!E;F-O9&4@86YD(&1E8V]D92!M90$!\r\n"+
-          " \r\nend\r\n";
-        check (uuD, encoded, originalText);
-
-        encoded = "begin 644 encoder.buf\n" +
-          "E2&D@5&AE<F4L('!L96%S92!E;F-O9&4@86YD(&1E8V]D92!M90$!\n"+
-          " \nend\n";
-        check (uuD, encoded, originalText);
-
-        encoded = "begin 644 encoder.buf\r" +
-          "E2&D@5&AE<F4L('!L96%S92!E;F-O9&4@86YD(&1E8V]D92!M90$!\r"+
-          " \rend\r";
-        check (uuD, encoded, originalText);
-
-        // Multi-line Unix text file
-
-        String s1 = "begin 644 f\n"+
-        "M3W)I9VYL(\"I(:2!4:&5R92P@<&QE87-E(&5N8V]D92!A;F0@9&5C;V1E(&UE\n"+
-        "M*@IA;F0@;64@06YD($UE(&%N1\"!M92!!;F0@344@04Y$($U%(%I80U8@,3(S\n"+
-        "-97)T\"E5)3U @45=%\"DUE\n"+
-        " \nend\n";
-
-        String s2 = "Orignl *Hi There, please encode and decode me*\n"+
-        "and me And Me anD me And ME AND ME ZXCV 123ert\n"+
-        "UIOP QWE\n";
-        check (uuD, s1, s2);
-
-        // Multi-line Windows text file
-
-        s1 = "begin 644 f\n"+
-        "M2&5L;&\\@22!A;2!A(&UU;'1I;&EN92!F:6QE#0IC<F5A=&5D(&]N(%=I;F1O\r\n"+
-        "M=W,L('1O('1E<W0@=&AE(%5516YC;V1E<@T*86YD(%551&5C;V1E<B!C;&%S\r\n"+
-        "$<V5S+G1O\r\n"+ " \r\nend\r\n";
-        s2="Hello I am a multiline file\r\n"+
-        "created on Windows, to test the UUEncoder\r\n"+
-        "and UUDecoder classes.";
-        check (uuD, s1, s2);
-    }
-
-    public static void check (UUDecoder uuD, String s, String original) throws Exception {
-        String decoded;
-        // do UU stuff
-        decoded = new String(uuD.decodeBuffer(s));
-        if (!decoded.equals (original)) {
-            throw new Exception ("decoded text not same as original");
-        }
-    }
-}
--- a/jdk/test/sun/misc/Encode/Encode.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 4041231
- * @summary Test UUEncoder.java for proper masking in encodeAtom
- * @modules java.base/sun.misc
- */
-
-import sun.misc.*;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-public class Encode {
-
-    public static void main(String[] args) throws Exception {
-        UUEncoder encoder = new UUEncoder("encode.buf");
-        byte[] buffer = new byte[3];
-
-        buffer[0] = -1;
-        buffer[1] = -1;
-        buffer[2] = -1;
-
-        ByteArrayInputStream in = new ByteArrayInputStream(buffer);
-        ByteArrayOutputStream out = new ByteArrayOutputStream(10);
-
-        encoder.encodeBuffer(in, out);
-        byte[] result = out.toByteArray();
-
-        if (result[22] == 31)
-            throw new RuntimeException("UUEncoder generates incorrect byte sequences in encodeAtom.");
-
-    }
-}
--- a/jdk/test/sun/misc/Encode/GetBytes.java	Fri Dec 18 10:00:55 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 5031097
- * @summary sun.misc.CharacterEncoder(ByteBuffer) is dumping too
- *      much information
- * @modules java.base/sun.misc
- * @author Brad Wetmore
- */
-
-import java.nio.*;
-import sun.misc.*;
-
-public class GetBytes {
-
-    public static void main(String args[]) throws Exception {
-
-        ByteBuffer bb = ByteBuffer.wrap(new byte [26 + 2]);
-
-        for (int i = 'a'; i < 'a' + bb.capacity(); i++) {
-            bb.put((byte)i);
-        }
-
-        /*
-         * Slice a subbuffer out of the original buffer.
-         */
-        bb.position(1);
-        bb.limit(bb.capacity() - 1);
-
-        ByteBuffer src = bb.slice();
-
-        CharacterEncoder e = new BASE64Encoder();
-        CharacterDecoder d = new BASE64Decoder();
-
-        String encoded = e.encodeBuffer(src);
-        ByteBuffer dst = d.decodeBufferToByteBuffer(encoded);
-
-        src.rewind();
-        dst.rewind();
-
-        if (src.compareTo(dst) != 0) {
-            throw new Exception("Didn't encode/decode correctly");
-        }
-    }
-}
--- a/jdk/test/sun/security/krb5/auto/MSOID2.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/krb5/auto/MSOID2.java	Tue Dec 22 13:41:12 2015 -0800
@@ -30,6 +30,7 @@
  */
 
 import sun.security.jgss.GSSUtil;
+import sun.security.util.HexDumpEncoder;
 
 // The basic krb5 test skeleton you can copy from
 public class MSOID2 {
@@ -69,7 +70,7 @@
                     nt[pos] = (byte)newLen;
                 }
                 t = nt;
-                new sun.misc.HexDumpEncoder().encodeBuffer(t, System.out);
+                new HexDumpEncoder().encodeBuffer(t, System.out);
             }
             if (t != null || !s.x().isEstablished()) t = s.take(t);
             if (c.x().isEstablished() && s.x().isEstablished()) break;
--- a/jdk/test/sun/security/mscapi/PublicKeyInterop.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.java	Tue Dec 22 13:41:12 2015 -0800
@@ -29,7 +29,7 @@
 import java.util.*;
 import javax.crypto.*;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 /*
  * Confirm interoperability of RSA public keys between SunMSCAPI and SunJCE
--- a/jdk/test/sun/security/mscapi/PublicKeyInterop.sh	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.sh	Tue Dec 22 13:41:12 2015 -0800
@@ -25,6 +25,7 @@
 
 # @test
 # @bug 6888925
+# @modules java.base/sun.security.util
 # @requires os.family == "windows"
 # @run shell PublicKeyInterop.sh
 # @summary SunMSCAPI's Cipher can't use RSA public keys obtained from other
--- a/jdk/test/sun/security/pkcs/pkcs7/SignerOrder.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/pkcs/pkcs7/SignerOrder.java	Tue Dec 22 13:41:12 2015 -0800
@@ -40,7 +40,7 @@
 import java.security.SignatureException;
 import java.security.cert.X509Certificate;
 import java.util.Date;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.pkcs.ContentInfo;
 import sun.security.pkcs.PKCS7;
 import sun.security.pkcs.SignerInfo;
--- a/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java	Tue Dec 22 13:41:12 2015 -0800
@@ -43,7 +43,7 @@
 import java.math.BigInteger;
 import java.security.InvalidKeyException;
 import java.util.Arrays;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.pkcs.PKCS8Key;
 import sun.security.provider.DSAPrivateKey;
 import sun.security.util.DerOutputStream;
--- a/jdk/test/sun/security/pkcs/pkcs9/UnknownAttribute.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/pkcs/pkcs9/UnknownAttribute.java	Tue Dec 22 13:41:12 2015 -0800
@@ -33,7 +33,7 @@
 import java.io.*;
 import java.util.Arrays;
 
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 import sun.security.pkcs.PKCS9Attribute;
 import sun.security.util.DerValue;
 import sun.security.util.ObjectIdentifier;
--- a/jdk/test/sun/security/x509/X500Name/NullX500Name.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/security/x509/X500Name/NullX500Name.java	Tue Dec 22 13:41:12 2015 -0800
@@ -32,7 +32,7 @@
 import java.util.Arrays;
 import sun.security.util.DerOutputStream;
 import sun.security.x509.*;
-import sun.misc.HexDumpEncoder;
+import sun.security.util.HexDumpEncoder;
 
 public class NullX500Name {
 
--- a/jdk/test/sun/tools/jinfo/JInfoSanityTest.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/tools/jinfo/JInfoSanityTest.java	Tue Dec 22 13:41:12 2015 -0800
@@ -71,7 +71,7 @@
         String unknownHost = "Oja781nh2ev7vcvbajdg-Sda1-C";
         OutputAnalyzer output = JInfoHelper.jinfoNoPid("med@" + unknownHost);
         assertNotEquals(output.getExitValue(), 0, "A non-zero exit code should be returned for invalid operation");
-        output.shouldContain("UnknownHostException: " + unknownHost);
+        output.shouldMatch(".*(Connection refused to host\\:|UnknownHostException\\:) " + unknownHost + ".*");
     }
 
 }
--- a/jdk/test/sun/tools/jps/TestJpsSanity.java	Fri Dec 18 10:00:55 2015 -0800
+++ b/jdk/test/sun/tools/jps/TestJpsSanity.java	Tue Dec 22 13:41:12 2015 -0800
@@ -62,7 +62,7 @@
         OutputAnalyzer output = JpsHelper.jps(invalidHostName);
         Asserts.assertNotEquals(output.getExitValue(), 0, "Exit code shouldn't be 0");
         Asserts.assertFalse(output.getStderr().isEmpty(), "Error output should not be empty");
-        output.shouldContain("Unknown host: " + invalidHostName);
+        output.shouldMatch(".*(RMI Registry not available at|Unknown host\\:) " + invalidHostName + ".*");
     }
 
 }
--- a/langtools/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/langtools/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -339,3 +339,4 @@
 8356d7a909a29f321e3eaf9d3c2bbc71648529e2 jdk9-b94
 c35ddcde581676275cfeff33e1a2b90b902593d9 jdk-9+95
 d2a44416cba39957ea231eedc2fb8aad7be1b30c jdk-9+96
+ae8cdc734bab4f19ef8babd2434dcf024672ad38 jdk-9+97
--- a/nashorn/.hgtags	Fri Dec 18 10:00:55 2015 -0800
+++ b/nashorn/.hgtags	Tue Dec 22 13:41:12 2015 -0800
@@ -330,3 +330,4 @@
 328932975c749ba7ae40cd5b63e3a7983b564936 jdk9-b94
 9d52f9bb589c4caa3617fe1cf11c72512ab8e973 jdk-9+95
 d52c09d5d98a81ee6102a25f662ec4b9ae614163 jdk-9+96
+2beaef2b6a880c0bff8c9f57ffca33477d647f8b jdk-9+97